Ignore:
Timestamp:
2012-08-24T14:07:52Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
041ab64
Parents:
bd29f9c9 (diff), db81577 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge with mainline

File:
1 edited

Legend:

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

    rbd29f9c9 rbeb9336  
    2929/** @addtogroup libext4
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        libext4_directory_index.c
    35  * @brief       Ext4 directory index operations.
     33 * @file  libext4_directory_index.c
     34 * @brief Ext4 directory index operations.
    3635 */
    3736
     
    4039#include <malloc.h>
    4140#include <sort.h>
    42 #include <string.h>
    4341#include "libext4.h"
    4442
     
    5250} ext4_dx_sort_entry_t;
    5351
    54 
    5552/** Get hash version used in directory index.
    5653 *
    57  * @param root_info     pointer to root info structure of index
    58  * @return                      hash algorithm version
     54 * @param root_info Pointer to root info structure of index
     55 *
     56 * @return Hash algorithm version
     57 *
    5958 */
    6059uint8_t ext4_directory_dx_root_info_get_hash_version(
    61                 ext4_directory_dx_root_info_t *root_info)
     60    ext4_directory_dx_root_info_t *root_info)
    6261{
    6362        return root_info->hash_version;
     
    6665/** Set hash version, that will be used in directory index.
    6766 *
    68  * @param root_info             pointer to root info structure of index
    69  * @param version               hash algorithm version
     67 * @param root_info Pointer to root info structure of index
     68 * @param version   Hash algorithm version
     69 *
    7070 */
    7171void ext4_directory_dx_root_info_set_hash_version(
    72                 ext4_directory_dx_root_info_t *root_info, uint8_t version)
     72    ext4_directory_dx_root_info_t *root_info, uint8_t version)
    7373{
    7474        root_info->hash_version = version;
     
    7777/** Get length of root_info structure in bytes.
    7878 *
    79  * @param root_info     pointer to root info structure of index
    80  * @return                      length of the structure
     79 * @param root_info Pointer to root info structure of index
     80 *
     81 * @return Length of the structure
     82 *
    8183 */
    8284uint8_t ext4_directory_dx_root_info_get_info_length(
    83                 ext4_directory_dx_root_info_t *root_info)
     85    ext4_directory_dx_root_info_t *root_info)
    8486{
    8587        return root_info->info_length;
     
    8890/** Set length of root_info structure in bytes.
    8991 *
    90  * @param root_info             pointer to root info structure of index
    91  * @param info_length   length of the structure
     92 * @param root_info   Pointer to root info structure of index
     93 * @param info_length Length of the structure
     94 *
    9295 */
    9396void ext4_directory_dx_root_info_set_info_length(
    94                 ext4_directory_dx_root_info_t *root_info, uint8_t info_length)
     97    ext4_directory_dx_root_info_t *root_info, uint8_t info_length)
    9598{
    9699        root_info->info_length = info_length;
     
    99102/** Get number of indirect levels of HTree.
    100103 *
    101  * @param root_info     pointer to root info structure of index
    102  * @return                      height of HTree (actually only 0 or 1)
     104 * @param root_info Pointer to root info structure of index
     105 *
     106 * @return Height of HTree (actually only 0 or 1)
     107 *
    103108 */
    104109uint8_t ext4_directory_dx_root_info_get_indirect_levels(
    105                 ext4_directory_dx_root_info_t *root_info)
     110    ext4_directory_dx_root_info_t *root_info)
    106111{
    107112        return root_info->indirect_levels;
     
    110115/** Set number of indirect levels of HTree.
    111116 *
    112  * @param root_info     pointer to root info structure of index
    113  * @param levels        height of HTree (actually only 0 or 1)
     117 * @param root_info Pointer to root info structure of index
     118 * @param levels    Height of HTree (actually only 0 or 1)
     119 *
    114120 */
    115121void ext4_directory_dx_root_info_set_indirect_levels(
    116                 ext4_directory_dx_root_info_t *root_info, uint8_t levels)
     122    ext4_directory_dx_root_info_t *root_info, uint8_t levels)
    117123{
    118124        root_info->indirect_levels = levels;
     
    121127/** Get maximum number of index node entries.
    122128 *
    123  * @param countlimit    pointer to counlimit structure
    124  * @return                              maximum of entries in node
     129 * @param countlimit Pointer to counlimit structure
     130 *
     131 * @return Maximum of entries in node
     132 *
    125133 */
    126134uint16_t ext4_directory_dx_countlimit_get_limit(
    127                 ext4_directory_dx_countlimit_t *countlimit)
     135    ext4_directory_dx_countlimit_t *countlimit)
    128136{
    129137        return uint16_t_le2host(countlimit->limit);
     
    132140/** Set maximum number of index node entries.
    133141 *
    134  * @param countlimit    pointer to counlimit structure
    135  * @param limit                 maximum of entries in node
     142 * @param countlimit Pointer to counlimit structure
     143 * @param limit      Maximum of entries in node
     144 *
    136145 */
    137146void ext4_directory_dx_countlimit_set_limit(
    138                 ext4_directory_dx_countlimit_t *countlimit, uint16_t limit)
     147    ext4_directory_dx_countlimit_t *countlimit, uint16_t limit)
    139148{
    140149        countlimit->limit = host2uint16_t_le(limit);
     
    143152/** Get current number of index node entries.
    144153 *
    145  * @param countlimit    pointer to counlimit structure
    146  * @return                              number of entries in node
     154 * @param countlimit Pointer to counlimit structure
     155 *
     156 * @return Number of entries in node
     157 *
    147158 */
    148159uint16_t ext4_directory_dx_countlimit_get_count(
    149                 ext4_directory_dx_countlimit_t *countlimit)
     160    ext4_directory_dx_countlimit_t *countlimit)
    150161{
    151162        return uint16_t_le2host(countlimit->count);
     
    154165/** Set current number of index node entries.
    155166 *
    156  * @param countlimit    pointer to counlimit structure
    157  * @param count                 number of entries in node
     167 * @param countlimit Pointer to counlimit structure
     168 * @param count      Number of entries in node
     169 *
    158170 */
    159171void ext4_directory_dx_countlimit_set_count(
    160                 ext4_directory_dx_countlimit_t *countlimit, uint16_t count)
     172    ext4_directory_dx_countlimit_t *countlimit, uint16_t count)
    161173{
    162174        countlimit->count = host2uint16_t_le(count);
     
    165177/** Get hash value of index entry.
    166178 *
    167  * @param entry         pointer to index entry
    168  * @return          hash value
     179 * @param entry Pointer to index entry
     180 *
     181 * @return Hash value
     182 *
    169183 */
    170184uint32_t ext4_directory_dx_entry_get_hash(ext4_directory_dx_entry_t *entry)
     
    173187}
    174188
    175 
    176189/** Set hash value of index entry.
    177190 *
    178  * @param entry         pointer to index entry
    179  * @param hash          hash value
     191 * @param entry Pointer to index entry
     192 * @param hash  Hash value
     193 *
    180194 */
    181195void ext4_directory_dx_entry_set_hash(ext4_directory_dx_entry_t *entry,
    182                 uint32_t hash)
     196    uint32_t hash)
    183197{
    184198        entry->hash = host2uint32_t_le(hash);
     
    187201/** Get block address where child node is located.
    188202 *
    189  * @param entry         pointer to index entry
    190  * @return          block address of child node
     203 * @param entry Pointer to index entry
     204 *
     205 * @return Block address of child node
     206 *
    191207 */
    192208uint32_t ext4_directory_dx_entry_get_block(ext4_directory_dx_entry_t *entry)
     
    197213/** Set block address where child node is located.
    198214 *
    199  * @param entry         pointer to index entry
    200  * @param block         block address of child node
     215 * @param entry Pointer to index entry
     216 * @param block Block address of child node
     217 *
    201218 */
    202219void ext4_directory_dx_entry_set_block(ext4_directory_dx_entry_t *entry,
    203                 uint32_t block)
     220    uint32_t block)
    204221{
    205222        entry->block = host2uint32_t_le(block);
    206223}
    207224
    208 
    209 /**************************************************************************/
    210 
    211225/** Initialize index structure of new directory.
    212226 *
    213  * @param dir   pointer to directory i-node
    214  * @return              error code
     227 * @param dir Pointer to directory i-node
     228 *
     229 * @return Error code
     230 *
    215231 */
    216232int ext4_directory_dx_init(ext4_inode_ref_t *dir)
    217233{
    218         int rc;
    219 
    220234        /* Load block 0, where will be index root located */
    221235        uint32_t fblock;
    222         rc = ext4_filesystem_get_inode_data_block_index(dir, 0, &fblock);
    223         if (rc != EOK) {
    224                 return rc;
    225         }
    226 
     236        int rc = ext4_filesystem_get_inode_data_block_index(dir, 0,
     237            &fblock);
     238        if (rc != EOK)
     239                return rc;
     240       
    227241        block_t *block;
    228242        rc = block_get(&block, dir->fs->device, fblock, BLOCK_FLAGS_NONE);
    229         if (rc != EOK) {
    230                 return rc;
    231         }
    232 
     243        if (rc != EOK)
     244                return rc;
     245       
    233246        /* Initialize pointers to data structures */
    234247        ext4_directory_dx_root_t *root = block->data;
    235248        ext4_directory_dx_root_info_t *info = &(root->info);
    236 
     249       
    237250        /* Initialize root info structure */
    238251        uint8_t hash_version =
    239                         ext4_superblock_get_default_hash_version(dir->fs->superblock);
    240 
     252            ext4_superblock_get_default_hash_version(dir->fs->superblock);
     253       
    241254        ext4_directory_dx_root_info_set_hash_version(info, hash_version);
    242255        ext4_directory_dx_root_info_set_indirect_levels(info, 0);
    243256        ext4_directory_dx_root_info_set_info_length(info, 8);
    244 
     257       
    245258        /* Set limit and current number of entries */
    246259        ext4_directory_dx_countlimit_t *countlimit =
    247                         (ext4_directory_dx_countlimit_t *)&root->entries;
     260            (ext4_directory_dx_countlimit_t *) &root->entries;
    248261        ext4_directory_dx_countlimit_set_count(countlimit, 1);
    249 
    250         uint32_t block_size = ext4_superblock_get_block_size(dir->fs->superblock);
    251         uint32_t entry_space = block_size - 2 * sizeof(ext4_directory_dx_dot_entry_t)
    252                 - sizeof(ext4_directory_dx_root_info_t);
     262       
     263        uint32_t block_size =
     264            ext4_superblock_get_block_size(dir->fs->superblock);
     265        uint32_t entry_space =
     266            block_size - 2 * sizeof(ext4_directory_dx_dot_entry_t) -
     267            sizeof(ext4_directory_dx_root_info_t);
    253268        uint16_t root_limit = entry_space / sizeof(ext4_directory_dx_entry_t);
    254269        ext4_directory_dx_countlimit_set_limit(countlimit, root_limit);
    255 
     270       
    256271        /* Append new block, where will be new entries inserted in the future */
    257272        uint32_t iblock;
     
    261276                return rc;
    262277        }
    263 
     278       
    264279        block_t *new_block;
    265280        rc = block_get(&new_block, dir->fs->device, fblock, BLOCK_FLAGS_NOREAD);
     
    268283                return rc;
    269284        }
    270 
     285       
    271286        /* Fill the whole block with empty entry */
    272287        ext4_directory_entry_ll_t *block_entry = new_block->data;
    273288        ext4_directory_entry_ll_set_entry_length(block_entry, block_size);
    274289        ext4_directory_entry_ll_set_inode(block_entry, 0);
    275 
     290       
    276291        new_block->dirty = true;
    277292        rc = block_put(new_block);
     
    280295                return rc;
    281296        }
    282 
     297       
    283298        /* Connect new block to the only entry in index */
    284299        ext4_directory_dx_entry_t *entry = root->entries;
    285300        ext4_directory_dx_entry_set_block(entry, iblock);
    286 
     301       
    287302        block->dirty = true;
    288 
    289         rc = block_put(block);
    290         if (rc != EOK) {
    291                 return rc;
    292         }
    293 
    294         return EOK;
     303       
     304        return block_put(block);
    295305}
    296306
    297307/** Initialize hash info structure necessary for index operations.
    298308 *
    299  * @param hinfo                 pointer to hinfo to be initialized
    300  * @param root_block    root block (number 0) of index
    301  * @param sb                    pointer to superblock
    302  * @param name_len              length of name to be computed hash value from
    303  * @param name                  name to be computed hash value from
    304  * @return                              error code
    305  */
    306 static int ext4_directory_hinfo_init(ext4_hash_info_t *hinfo, block_t *root_block,
    307                 ext4_superblock_t *sb, size_t name_len, const char *name)
    308 {
    309 
    310         ext4_directory_dx_root_t *root = (ext4_directory_dx_root_t *)root_block->data;
    311 
    312         if (root->info.hash_version != EXT4_HASH_VERSION_TEA &&
    313                         root->info.hash_version != EXT4_HASH_VERSION_HALF_MD4 &&
    314                         root->info.hash_version != EXT4_HASH_VERSION_LEGACY) {
     309 * @param hinfo      Pointer to hinfo to be initialized
     310 * @param root_block Root block (number 0) of index
     311 * @param sb         Pointer to superblock
     312 * @param name_len   Length of name to be computed hash value from
     313 * @param name       Name to be computed hash value from
     314 *
     315 * @return Error code
     316 *
     317 */
     318static int ext4_directory_hinfo_init(ext4_hash_info_t *hinfo,
     319    block_t *root_block, ext4_superblock_t *sb, size_t name_len,
     320    const char *name)
     321{
     322        ext4_directory_dx_root_t *root =
     323            (ext4_directory_dx_root_t *) root_block->data;
     324       
     325        if ((root->info.hash_version != EXT4_HASH_VERSION_TEA) &&
     326            (root->info.hash_version != EXT4_HASH_VERSION_HALF_MD4) &&
     327            (root->info.hash_version != EXT4_HASH_VERSION_LEGACY))
    315328                return EXT4_ERR_BAD_DX_DIR;
    316         }
    317 
     329       
    318330        /* Check unused flags */
    319         if (root->info.unused_flags != 0) {
     331        if (root->info.unused_flags != 0)
    320332                return EXT4_ERR_BAD_DX_DIR;
    321         }
    322 
     333       
    323334        /* Check indirect levels */
    324         if (root->info.indirect_levels > 1) {
     335        if (root->info.indirect_levels > 1)
    325336                return EXT4_ERR_BAD_DX_DIR;
    326         }
    327 
     337       
    328338        /* Check if node limit is correct */
    329339        uint32_t block_size = ext4_superblock_get_block_size(sb);
     
    331341        entry_space -= 2 * sizeof(ext4_directory_dx_dot_entry_t);
    332342        entry_space -= sizeof(ext4_directory_dx_root_info_t);
    333     entry_space = entry_space / sizeof(ext4_directory_dx_entry_t);
    334 
    335     uint16_t limit = ext4_directory_dx_countlimit_get_limit((ext4_directory_dx_countlimit_t *)&root->entries);
    336     if (limit != entry_space) {
    337         return EXT4_ERR_BAD_DX_DIR;
    338         }
    339 
    340     /* Check hash version and modify if necessary */
    341         hinfo->hash_version = ext4_directory_dx_root_info_get_hash_version(&root->info);
    342         if ((hinfo->hash_version <= EXT4_HASH_VERSION_TEA)
    343                         && (ext4_superblock_has_flag(sb, EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH))) {
     343        entry_space = entry_space / sizeof(ext4_directory_dx_entry_t);
     344       
     345        uint16_t limit = ext4_directory_dx_countlimit_get_limit(
     346            (ext4_directory_dx_countlimit_t *) &root->entries);
     347        if (limit != entry_space)
     348                return EXT4_ERR_BAD_DX_DIR;
     349       
     350        /* Check hash version and modify if necessary */
     351        hinfo->hash_version =
     352            ext4_directory_dx_root_info_get_hash_version(&root->info);
     353        if ((hinfo->hash_version <= EXT4_HASH_VERSION_TEA) &&
     354            (ext4_superblock_has_flag(sb, EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH))) {
    344355                /* 3 is magic from ext4 linux implementation */
    345356                hinfo->hash_version += 3;
    346357        }
    347 
     358       
    348359        /* Load hash seed from superblock */
    349360        hinfo->seed = ext4_superblock_get_hash_seed(sb);
    350 
     361       
    351362        /* Compute hash value of name */
    352         if (name) {
     363        if (name)
    353364                ext4_hash_string(hinfo, name_len, name);
    354         }
    355 
     365       
    356366        return EOK;
    357367}
     
    359369/** Walk through index tree and load leaf with corresponding hash value.
    360370 *
    361  * @param hinfo                 initialized hash info structure
    362  * @param inode_ref     current i-node
    363  * @param root_block    root block (iblock 0), where is root node located
    364  * @param dx_block              pointer to leaf node in dx_blocks array
    365  * @param dx_blocks             array with the whole path from root to leaf
    366  * @return                              error code
     371 * @param hinfo      Initialized hash info structure
     372 * @param inode_ref  Current i-node
     373 * @param root_block Root block (iblock 0), where is root node located
     374 * @param dx_block   Pointer to leaf node in dx_blocks array
     375 * @param dx_blocks  Array with the whole path from root to leaf
     376 *
     377 * @return Error code
     378 *
    367379 */
    368380static int ext4_directory_dx_get_leaf(ext4_hash_info_t *hinfo,
    369                 ext4_inode_ref_t *inode_ref, block_t *root_block,
    370                 ext4_directory_dx_block_t **dx_block, ext4_directory_dx_block_t *dx_blocks)
    371 {
    372         int rc;
    373 
     381    ext4_inode_ref_t *inode_ref, block_t *root_block,
     382    ext4_directory_dx_block_t **dx_block, ext4_directory_dx_block_t *dx_blocks)
     383{
    374384        ext4_directory_dx_block_t *tmp_dx_block = dx_blocks;
    375 
    376         ext4_directory_dx_root_t *root = (ext4_directory_dx_root_t *)root_block->data;
    377         ext4_directory_dx_entry_t *entries = (ext4_directory_dx_entry_t *)&root->entries;
    378 
    379         uint16_t limit = ext4_directory_dx_countlimit_get_limit((ext4_directory_dx_countlimit_t *)entries);
    380         uint8_t indirect_level = ext4_directory_dx_root_info_get_indirect_levels(&root->info);
    381 
     385        ext4_directory_dx_root_t *root =
     386            (ext4_directory_dx_root_t *) root_block->data;
     387        ext4_directory_dx_entry_t *entries =
     388            (ext4_directory_dx_entry_t *) &root->entries;
     389       
     390        uint16_t limit = ext4_directory_dx_countlimit_get_limit(
     391            (ext4_directory_dx_countlimit_t *) entries);
     392        uint8_t indirect_level =
     393            ext4_directory_dx_root_info_get_indirect_levels(&root->info);
     394       
    382395        block_t *tmp_block = root_block;
    383         ext4_directory_dx_entry_t *p, *q, *m, *at;
    384 
     396        ext4_directory_dx_entry_t *p;
     397        ext4_directory_dx_entry_t *q;
     398        ext4_directory_dx_entry_t *m;
     399        ext4_directory_dx_entry_t *at;
     400       
    385401        /* Walk through the index tree */
    386402        while (true) {
    387 
    388                 uint16_t count = ext4_directory_dx_countlimit_get_count((ext4_directory_dx_countlimit_t *)entries);
    389                 if ((count == 0) || (count > limit)) {
     403                uint16_t count = ext4_directory_dx_countlimit_get_count(
     404                    (ext4_directory_dx_countlimit_t *) entries);
     405                if ((count == 0) || (count > limit))
    390406                        return EXT4_ERR_BAD_DX_DIR;
    391                 }
    392 
    393 
     407               
    394408                /* Do binary search in every node */
    395409                p = entries + 1;
    396410                q = entries + count - 1;
    397 
     411               
    398412                while (p <= q) {
    399413                        m = p + (q - p) / 2;
    400                         if (ext4_directory_dx_entry_get_hash(m) > hinfo->hash) {
     414                        if (ext4_directory_dx_entry_get_hash(m) > hinfo->hash)
    401415                                q = m - 1;
    402                         } else {
     416                        else
    403417                                p = m + 1;
    404                         }
    405418                }
    406 
     419               
    407420                at = p - 1;
    408 
     421               
    409422                /* Write results */
    410423                tmp_dx_block->block = tmp_block;
    411424                tmp_dx_block->entries = entries;
    412425                tmp_dx_block->position = at;
    413 
     426               
    414427                /* Is algorithm in the leaf? */
    415         if (indirect_level == 0) {
    416                 *dx_block = tmp_dx_block;
    417                 return EOK;
    418         }
    419 
    420         /* Goto child node */
     428                if (indirect_level == 0) {
     429                        *dx_block = tmp_dx_block;
     430                        return EOK;
     431                }
     432               
     433                /* Goto child node */
    421434                uint32_t next_block = ext4_directory_dx_entry_get_block(at);
    422 
    423         indirect_level--;
    424 
    425         uint32_t fblock;
    426         rc = ext4_filesystem_get_inode_data_block_index(
    427                         inode_ref, next_block, &fblock);
    428         if (rc != EOK) {
    429                 return rc;
    430         }
    431 
    432         rc = block_get(&tmp_block, inode_ref->fs->device, fblock, BLOCK_FLAGS_NONE);
    433         if (rc != EOK) {
    434                 return rc;
    435         }
    436 
     435               
     436                indirect_level--;
     437               
     438                uint32_t fblock;
     439                int rc = ext4_filesystem_get_inode_data_block_index(inode_ref,
     440                    next_block, &fblock);
     441                if (rc != EOK)
     442                        return rc;
     443               
     444                rc = block_get(&tmp_block, inode_ref->fs->device, fblock,
     445                    BLOCK_FLAGS_NONE);
     446                if (rc != EOK)
     447                        return rc;
     448               
    437449                entries = ((ext4_directory_dx_node_t *) tmp_block->data)->entries;
    438450                limit = ext4_directory_dx_countlimit_get_limit(
    439                                 (ext4_directory_dx_countlimit_t *)entries);
    440 
    441         uint16_t entry_space = ext4_superblock_get_block_size(inode_ref->fs->superblock)
    442                         - sizeof(ext4_directory_dx_dot_entry_t);
    443         entry_space = entry_space / sizeof(ext4_directory_dx_entry_t);
    444 
    445 
     451                    (ext4_directory_dx_countlimit_t *) entries);
     452               
     453                uint16_t entry_space =
     454                    ext4_superblock_get_block_size(inode_ref->fs->superblock) -
     455                    sizeof(ext4_directory_dx_dot_entry_t);
     456                entry_space = entry_space / sizeof(ext4_directory_dx_entry_t);
     457               
    446458                if (limit != entry_space) {
    447459                        block_put(tmp_block);
    448                 return EXT4_ERR_BAD_DX_DIR;
     460                        return EXT4_ERR_BAD_DX_DIR;
    449461                }
    450 
     462               
    451463                ++tmp_dx_block;
    452464        }
    453 
     465       
    454466        /* Unreachable */
    455467        return EOK;
    456468}
    457469
    458 
    459470/** Check if the the next block would be checked during entry search.
    460471 *
    461  * @param inode_ref                     directory i-node
    462  * @param hash                          hash value to check
    463  * @param dx_block                      current block
    464  * @param dx_blocks                     aray with path from root to leaf node
    465  * @return                                      error code
    466  */
    467 static int ext4_directory_dx_next_block(ext4_inode_ref_t *inode_ref, uint32_t hash,
    468                 ext4_directory_dx_block_t *dx_block, ext4_directory_dx_block_t *dx_blocks)
    469 {
    470         int rc;
    471 
    472     uint32_t num_handles = 0;
    473     ext4_directory_dx_block_t *p = dx_block;
    474 
    475     /* Try to find data block with next bunch of entries */
    476     while (1) {
    477 
    478         p->position++;
    479         uint16_t count = ext4_directory_dx_countlimit_get_count(
    480                         (ext4_directory_dx_countlimit_t *)p->entries);
    481 
    482         if (p->position < p->entries + count) {
    483                 break;
    484         }
    485 
    486         if (p == dx_blocks) {
    487                 return 0;
    488         }
    489 
    490         num_handles++;
    491         p--;
    492     }
    493 
    494     /* Check hash collision (if not occured - no next block cannot be used) */
    495     uint32_t current_hash = ext4_directory_dx_entry_get_hash(p->position);
    496     if ((hash & 1) == 0) {
    497         if ((current_hash & ~1) != hash) {
    498                 return 0;
    499         }
    500     }
    501 
    502     /* Fill new path */
    503     while (num_handles--) {
    504 
    505         uint32_t block_idx = ext4_directory_dx_entry_get_block(p->position);
    506         uint32_t block_addr;
    507         rc = ext4_filesystem_get_inode_data_block_index(inode_ref, block_idx, &block_addr);
    508         if (rc != EOK) {
    509                 return rc;
    510         }
    511 
    512         block_t *block;
    513         rc = block_get(&block, inode_ref->fs->device, block_addr, BLOCK_FLAGS_NONE);
    514         if (rc != EOK) {
    515                 return rc;
    516         }
    517 
    518         p++;
    519 
    520         /* Don't forget to put old block (prevent memory leak) */
    521         block_put(p->block);
    522 
    523         p->block = block;
    524         p->entries = ((ext4_directory_dx_node_t *) block->data)->entries;
    525         p->position = p->entries;
    526     }
    527 
    528     return 1;
    529 
     472 * @param inode_ref Directory i-node
     473 * @param hash      Hash value to check
     474 * @param dx_block  Current block
     475 * @param dx_blocks Array with path from root to leaf node
     476 *
     477 * @return Error code
     478 *
     479 */
     480static int ext4_directory_dx_next_block(ext4_inode_ref_t *inode_ref,
     481    uint32_t hash, ext4_directory_dx_block_t *dx_block,
     482    ext4_directory_dx_block_t *dx_blocks)
     483{
     484        uint32_t num_handles = 0;
     485        ext4_directory_dx_block_t *p = dx_block;
     486       
     487        /* Try to find data block with next bunch of entries */
     488        while (true) {
     489                p->position++;
     490                uint16_t count = ext4_directory_dx_countlimit_get_count(
     491                    (ext4_directory_dx_countlimit_t *) p->entries);
     492               
     493                if (p->position < p->entries + count)
     494                        break;
     495               
     496                if (p == dx_blocks)
     497                        return EOK;
     498               
     499                num_handles++;
     500                p--;
     501        }
     502       
     503        /* Check hash collision (if not occured - no next block cannot be used) */
     504        uint32_t current_hash = ext4_directory_dx_entry_get_hash(p->position);
     505        if ((hash & 1) == 0) {
     506                if ((current_hash & ~1) != hash)
     507                        return 0;
     508        }
     509       
     510        /* Fill new path */
     511        while (num_handles--) {
     512                uint32_t block_idx =
     513                    ext4_directory_dx_entry_get_block(p->position);
     514                uint32_t block_addr;
     515               
     516                int rc = ext4_filesystem_get_inode_data_block_index(inode_ref,
     517                    block_idx, &block_addr);
     518                if (rc != EOK)
     519                        return rc;
     520               
     521                block_t *block;
     522                rc = block_get(&block, inode_ref->fs->device, block_addr, BLOCK_FLAGS_NONE);
     523                if (rc != EOK)
     524                        return rc;
     525               
     526                p++;
     527               
     528                /* Don't forget to put old block (prevent memory leak) */
     529                block_put(p->block);
     530               
     531                p->block = block;
     532                p->entries = ((ext4_directory_dx_node_t *) block->data)->entries;
     533                p->position = p->entries;
     534        }
     535       
     536        return ENOENT;
    530537}
    531538
    532539/** Try to find directory entry using directory index.
    533540 *
    534  * @param result                output value - if entry will be found,
    535  *                      than will be passed through this parameter
    536  * @param inode_ref             directory i-node
    537  * @param name_len              length of name to be found
    538  * @param name                  name to be found
    539  * @return                              error code
     541 * @param result    Output value - if entry will be found,
     542 *                  than will be passed through this parameter
     543 * @param inode_ref Directory i-node
     544 * @param name_len  Length of name to be found
     545 * @param name      Name to be found
     546 *
     547 * @return Error code
     548 *
    540549 */
    541550int ext4_directory_dx_find_entry(ext4_directory_search_result_t *result,
    542                 ext4_inode_ref_t *inode_ref, size_t name_len, const char *name)
    543 {
    544         int rc;
    545 
     551    ext4_inode_ref_t *inode_ref, size_t name_len, const char *name)
     552{
    546553        /* Load direct block 0 (index root) */
    547554        uint32_t root_block_addr;
    548         rc = ext4_filesystem_get_inode_data_block_index(inode_ref, 0, &root_block_addr);
    549         if (rc != EOK) {
    550                 return rc;
    551         }
    552 
     555        int rc = ext4_filesystem_get_inode_data_block_index(inode_ref, 0,
     556            &root_block_addr);
     557        if (rc != EOK)
     558                return rc;
     559       
    553560        ext4_filesystem_t *fs = inode_ref->fs;
    554 
     561       
    555562        block_t *root_block;
    556         rc = block_get(&root_block, fs->device, root_block_addr, BLOCK_FLAGS_NONE);
    557         if (rc != EOK) {
    558                 return rc;
    559         }
    560 
     563        rc = block_get(&root_block, fs->device, root_block_addr,
     564            BLOCK_FLAGS_NONE);
     565        if (rc != EOK)
     566                return rc;
     567       
    561568        /* Initialize hash info (compute hash value) */
    562569        ext4_hash_info_t hinfo;
    563         rc = ext4_directory_hinfo_init(&hinfo, root_block, fs->superblock, name_len, name);
     570        rc = ext4_directory_hinfo_init(&hinfo, root_block, fs->superblock,
     571            name_len, name);
    564572        if (rc != EOK) {
    565573                block_put(root_block);
    566574                return EXT4_ERR_BAD_DX_DIR;
    567575        }
    568 
    569         /* Hardcoded number 2 means maximum height of index tree, specified in linux driver */
     576       
     577        /*
     578         * Hardcoded number 2 means maximum height of index tree,
     579         * specified in the Linux driver.
     580         */
    570581        ext4_directory_dx_block_t dx_blocks[2];
    571         ext4_directory_dx_block_t *dx_block, *tmp;
    572         rc = ext4_directory_dx_get_leaf(&hinfo, inode_ref, root_block, &dx_block, dx_blocks);
     582        ext4_directory_dx_block_t *dx_block;
     583        ext4_directory_dx_block_t *tmp;
     584       
     585        rc = ext4_directory_dx_get_leaf(&hinfo, inode_ref, root_block,
     586            &dx_block, dx_blocks);
    573587        if (rc != EOK) {
    574588                block_put(root_block);
    575589                return EXT4_ERR_BAD_DX_DIR;
    576590        }
    577 
     591       
    578592        do {
    579593                /* Load leaf block */
    580                 uint32_t leaf_block_idx = ext4_directory_dx_entry_get_block(dx_block->position);
     594                uint32_t leaf_block_idx =
     595                    ext4_directory_dx_entry_get_block(dx_block->position);
    581596                uint32_t leaf_block_addr;
    582         rc = ext4_filesystem_get_inode_data_block_index(inode_ref, leaf_block_idx, &leaf_block_addr);
    583         if (rc != EOK) {
    584                 goto cleanup;
    585         }
    586 
    587         block_t *leaf_block;
    588                 rc = block_get(&leaf_block, fs->device, leaf_block_addr, BLOCK_FLAGS_NONE);
    589                 if (rc != EOK) {
     597               
     598                rc = ext4_filesystem_get_inode_data_block_index(inode_ref,
     599                    leaf_block_idx, &leaf_block_addr);
     600                if (rc != EOK)
    590601                        goto cleanup;
    591                 }
    592 
     602               
     603                block_t *leaf_block;
     604                rc = block_get(&leaf_block, fs->device, leaf_block_addr,
     605                    BLOCK_FLAGS_NONE);
     606                if (rc != EOK)
     607                        goto cleanup;
     608               
    593609                /* Linear search inside block */
    594610                ext4_directory_entry_ll_t *res_dentry;
    595                 rc = ext4_directory_find_in_block(leaf_block, fs->superblock, name_len, name, &res_dentry);
    596 
     611                rc = ext4_directory_find_in_block(leaf_block, fs->superblock,
     612                    name_len, name, &res_dentry);
     613               
    597614                /* Found => return it */
    598615                if (rc == EOK) {
     
    601618                        goto cleanup;
    602619                }
    603 
     620               
    604621                /* Not found, leave untouched */
    605622                block_put(leaf_block);
    606 
    607                 if (rc != ENOENT) {
     623               
     624                if (rc != ENOENT)
    608625                        goto cleanup;
    609                 }
    610 
     626               
    611627                /* check if the next block could be checked */
    612                 rc = ext4_directory_dx_next_block(inode_ref, hinfo.hash, dx_block, &dx_blocks[0]);
    613                 if (rc < 0) {
     628                rc = ext4_directory_dx_next_block(inode_ref, hinfo.hash,
     629                    dx_block, &dx_blocks[0]);
     630                if (rc < 0)
    614631                        goto cleanup;
    615                 }
    616 
    617         } while (rc == 1);
    618 
     632        } while (rc == ENOENT);
     633       
    619634        /* Entry not found */
    620635        rc = ENOENT;
    621 
     636       
    622637cleanup:
    623 
    624638        /* The whole path must be released (preventing memory leak) */
    625639        tmp = dx_blocks;
     640       
    626641        while (tmp <= dx_block) {
    627642                block_put(tmp->block);
    628643                ++tmp;
    629644        }
     645       
    630646        return rc;
    631647}
     
    635651 * It can compare two entries by hash value.
    636652 *
    637  * @param arg1          first entry
    638  * @param arg2          second entry
    639  * @param dummy         unused parameter, can be NULL
    640  * @return                      classic compare result (0: equal, -1: arg1 < arg2, 1: arg1 > arg2)
     653 * @param arg1  First entry
     654 * @param arg2  Second entry
     655 * @param dummy Unused parameter, can be NULL
     656 *
     657 * @return Classic compare result
     658 *         (0: equal, -1: arg1 < arg2, 1: arg1 > arg2)
     659 *
    641660 */
    642661static int ext4_directory_dx_entry_comparator(void *arg1, void *arg2, void *dummy)
     
    644663        ext4_dx_sort_entry_t *entry1 = arg1;
    645664        ext4_dx_sort_entry_t *entry2 = arg2;
    646 
    647         if (entry1->hash == entry2->hash) {
     665       
     666        if (entry1->hash == entry2->hash)
    648667                return 0;
    649         }
    650 
    651         if (entry1->hash < entry2->hash) {
     668       
     669        if (entry1->hash < entry2->hash)
    652670                return -1;
    653         } else {
     671        else
    654672                return 1;
    655         }
    656 
    657673}
    658674
     
    661677 * Note that space for new entry must be checked by caller.
    662678 *
    663  * @param index_block           block where to insert new entry
    664  * @param hash                          hash value covered by child node
    665  * @param iblock                        logical number of child block
     679 * @param index_block Block where to insert new entry
     680 * @param hash        Hash value covered by child node
     681 * @param iblock      Logical number of child block
    666682 *
    667683 */
    668684static void ext4_directory_dx_insert_entry(
    669                 ext4_directory_dx_block_t *index_block, uint32_t hash, uint32_t iblock)
     685    ext4_directory_dx_block_t *index_block, uint32_t hash, uint32_t iblock)
    670686{
    671687        ext4_directory_dx_entry_t *old_index_entry = index_block->position;
    672688        ext4_directory_dx_entry_t *new_index_entry = old_index_entry + 1;
    673 
     689       
    674690        ext4_directory_dx_countlimit_t *countlimit =
    675                         (ext4_directory_dx_countlimit_t *)index_block->entries;
     691            (ext4_directory_dx_countlimit_t *) index_block->entries;
    676692        uint32_t count = ext4_directory_dx_countlimit_get_count(countlimit);
    677 
     693       
    678694        ext4_directory_dx_entry_t *start_index = index_block->entries;
    679         size_t bytes = (void *)(start_index + count) - (void *)(new_index_entry);
    680 
     695        size_t bytes = (void *) (start_index + count) - (void *) (new_index_entry);
     696       
    681697        memmove(new_index_entry + 1, new_index_entry, bytes);
    682 
     698       
    683699        ext4_directory_dx_entry_set_block(new_index_entry, iblock);
    684700        ext4_directory_dx_entry_set_hash(new_index_entry, hash);
    685 
     701       
    686702        ext4_directory_dx_countlimit_set_count(countlimit, count + 1);
    687 
     703       
    688704        index_block->block->dirty = true;
    689705}
     
    691707/** Split directory entries to two parts preventing node overflow.
    692708 *
    693  * @param inode_ref                     directory i-node
    694  * @param hinfo                         hash info
    695  * @param old_data_block        block with data to be split
    696  * @param index_block           block where index entries are located
    697  * @param new_data_block        output value for newly allocated data block
     709 * @param inode_ref      Directory i-node
     710 * @param hinfo          Hash info
     711 * @param old_data_block Block with data to be split
     712 * @param index_block    Block where index entries are located
     713 * @param new_data_block Output value for newly allocated data block
     714 *
    698715 */
    699716static int ext4_directory_dx_split_data(ext4_inode_ref_t *inode_ref,
    700                 ext4_hash_info_t *hinfo, block_t *old_data_block,
    701                 ext4_directory_dx_block_t *index_block, block_t **new_data_block)
     717    ext4_hash_info_t *hinfo, block_t *old_data_block,
     718    ext4_directory_dx_block_t *index_block, block_t **new_data_block)
    702719{
    703720        int rc = EOK;
    704 
     721       
    705722        /* Allocate buffer for directory entries */
    706723        uint32_t block_size =
    707                         ext4_superblock_get_block_size(inode_ref->fs->superblock);
     724            ext4_superblock_get_block_size(inode_ref->fs->superblock);
    708725        void *entry_buffer = malloc(block_size);
    709         if (entry_buffer == NULL) {
     726        if (entry_buffer == NULL)
    710727                return ENOMEM;
    711         }
    712 
     728       
    713729        /* dot entry has the smallest size available */
    714         uint32_t max_entry_count =  block_size / sizeof(ext4_directory_dx_dot_entry_t);
    715 
     730        uint32_t max_entry_count =
     731            block_size / sizeof(ext4_directory_dx_dot_entry_t);
     732       
    716733        /* Allocate sort entry */
    717         ext4_dx_sort_entry_t *sort_array = malloc(max_entry_count * sizeof(ext4_dx_sort_entry_t));
     734        ext4_dx_sort_entry_t *sort_array =
     735            malloc(max_entry_count * sizeof(ext4_dx_sort_entry_t));
    718736        if (sort_array == NULL) {
    719737                free(entry_buffer);
    720738                return ENOMEM;
    721739        }
    722 
     740       
    723741        uint32_t idx = 0;
    724742        uint32_t real_size = 0;
    725 
     743       
    726744        /* Initialize hinfo */
    727745        ext4_hash_info_t tmp_hinfo;
    728746        memcpy(&tmp_hinfo, hinfo, sizeof(ext4_hash_info_t));
    729 
     747       
    730748        /* Load all valid entries to the buffer */
    731749        ext4_directory_entry_ll_t *dentry = old_data_block->data;
    732750        void *entry_buffer_ptr = entry_buffer;
    733751        while ((void *)dentry < old_data_block->data + block_size) {
    734 
    735752                /* Read only valid entries */
    736753                if (ext4_directory_entry_ll_get_inode(dentry) != 0) {
    737 
    738754                        uint8_t len = ext4_directory_entry_ll_get_name_length(
    739                                         inode_ref->fs->superblock, dentry);
    740                         ext4_hash_string(&tmp_hinfo, len, (char *)dentry->name);
    741 
     755                            inode_ref->fs->superblock, dentry);
     756                        ext4_hash_string(&tmp_hinfo, len, (char *) dentry->name);
     757                       
    742758                        uint32_t rec_len = 8 + len;
    743 
    744                         if ((rec_len % 4) != 0) {
     759                       
     760                        if ((rec_len % 4) != 0)
    745761                                rec_len += 4 - (rec_len % 4);
    746                         }
    747 
     762                       
    748763                        memcpy(entry_buffer_ptr, dentry, rec_len);
    749 
     764                       
    750765                        sort_array[idx].dentry = entry_buffer_ptr;
    751766                        sort_array[idx].rec_len = rec_len;
    752767                        sort_array[idx].hash = tmp_hinfo.hash;
    753 
     768                       
    754769                        entry_buffer_ptr += rec_len;
    755770                        real_size += rec_len;
    756771                        idx++;
    757772                }
    758 
    759                 dentry = (void *)dentry + ext4_directory_entry_ll_get_entry_length(dentry);
    760         }
    761 
     773               
     774                dentry = (void *) dentry +
     775                    ext4_directory_entry_ll_get_entry_length(dentry);
     776        }
     777       
    762778        /* Sort all entries */
    763779        qsort(sort_array, idx, sizeof(ext4_dx_sort_entry_t),
    764                         ext4_directory_dx_entry_comparator, NULL);
    765 
     780            ext4_directory_dx_entry_comparator, NULL);
     781       
    766782        /* Allocate new block for store the second part of entries */
    767783        uint32_t new_fblock;
    768784        uint32_t new_iblock;
    769         rc = ext4_filesystem_append_inode_block(inode_ref, &new_fblock, &new_iblock);
     785        rc = ext4_filesystem_append_inode_block(inode_ref, &new_fblock,
     786            &new_iblock);
    770787        if (rc != EOK) {
    771788                free(sort_array);
     
    773790                return rc;
    774791        }
    775 
     792       
    776793        /* Load new block */
    777794        block_t *new_data_block_tmp;
    778795        rc = block_get(&new_data_block_tmp, inode_ref->fs->device,
    779                         new_fblock, BLOCK_FLAGS_NOREAD);
     796            new_fblock, BLOCK_FLAGS_NOREAD);
    780797        if (rc != EOK) {
    781798                free(sort_array);
     
    783800                return rc;
    784801        }
    785 
    786         /* Distribute entries to two blocks (by size)
     802       
     803        /*
     804         * Distribute entries to two blocks (by size)
    787805         * - compute the half
    788806         */
     
    796814                        break;
    797815                }
    798 
     816               
    799817                current_size += sort_array[i].rec_len;
    800818        }
    801 
     819       
    802820        /* Check hash collision */
    803821        uint32_t continued = 0;
    804         if (new_hash == sort_array[mid-1].hash) {
     822        if (new_hash == sort_array[mid-1].hash)
    805823                continued = 1;
    806         }
    807 
     824       
    808825        uint32_t offset = 0;
    809826        void *ptr;
    810 
     827       
    811828        /* First part - to the old block */
    812829        for (uint32_t i = 0; i < mid; ++i) {
    813830                ptr = old_data_block->data + offset;
    814831                memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len);
    815 
     832               
    816833                ext4_directory_entry_ll_t *tmp = ptr;
    817                 if (i < (mid - 1)) {
    818                         ext4_directory_entry_ll_set_entry_length(tmp, sort_array[i].rec_len);
    819                 } else {
    820                         ext4_directory_entry_ll_set_entry_length(tmp, block_size - offset);
    821                 }
    822 
     834                if (i < (mid - 1))
     835                        ext4_directory_entry_ll_set_entry_length(tmp,
     836                            sort_array[i].rec_len);
     837                else
     838                        ext4_directory_entry_ll_set_entry_length(tmp,
     839                            block_size - offset);
     840               
    823841                offset += sort_array[i].rec_len;
    824842        }
    825 
     843       
    826844        /* Second part - to the new block */
    827845        offset = 0;
     
    829847                ptr = new_data_block_tmp->data + offset;
    830848                memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len);
    831 
     849               
    832850                ext4_directory_entry_ll_t *tmp = ptr;
    833                 if (i < (idx - 1)) {
    834                         ext4_directory_entry_ll_set_entry_length(tmp, sort_array[i].rec_len);
    835                 } else {
    836                         ext4_directory_entry_ll_set_entry_length(tmp, block_size - offset);
    837                 }
    838 
     851                if (i < (idx - 1))
     852                        ext4_directory_entry_ll_set_entry_length(tmp,
     853                            sort_array[i].rec_len);
     854                else
     855                        ext4_directory_entry_ll_set_entry_length(tmp,
     856                            block_size - offset);
     857               
    839858                offset += sort_array[i].rec_len;
    840859        }
    841 
     860       
    842861        /* Do some steps to finish operation */
    843862        old_data_block->dirty = true;
    844863        new_data_block_tmp->dirty = true;
    845 
     864       
    846865        free(sort_array);
    847866        free(entry_buffer);
    848 
    849         ext4_directory_dx_insert_entry(index_block, new_hash + continued, new_iblock);
    850 
     867       
     868        ext4_directory_dx_insert_entry(index_block, new_hash + continued,
     869            new_iblock);
     870       
    851871        *new_data_block = new_data_block_tmp;
    852 
     872       
    853873        return EOK;
    854874}
     
    856876/** Split index node and maybe some parent nodes in the tree hierarchy.
    857877 *
    858  * @param inode_ref             directory i-node
    859  * @param dx_blocks             array with path from root to leaf node
    860  * @param dx_block              leaf block to be split if needed
    861  * @return                              error code
     878 * @param inode_ref Directory i-node
     879 * @param dx_blocks Array with path from root to leaf node
     880 * @param dx_block  Leaf block to be split if needed
     881 *
     882 * @return Error code
     883 *
    862884 */
    863885static int ext4_directory_dx_split_index(ext4_inode_ref_t *inode_ref,
    864886                ext4_directory_dx_block_t *dx_blocks, ext4_directory_dx_block_t *dx_block)
    865887{
    866         int rc;
    867 
    868888        ext4_directory_dx_entry_t *entries;
    869         if (dx_block == dx_blocks) {
    870                 entries = ((ext4_directory_dx_root_t *) dx_block->block->data)->entries;
    871         } else {
    872                 entries = ((ext4_directory_dx_node_t *) dx_block->block->data)->entries;
    873         }
    874 
     889        if (dx_block == dx_blocks)
     890                entries =
     891                    ((ext4_directory_dx_root_t *) dx_block->block->data)->entries;
     892        else
     893                entries =
     894                    ((ext4_directory_dx_node_t *) dx_block->block->data)->entries;
     895       
    875896        ext4_directory_dx_countlimit_t *countlimit =
    876                         (ext4_directory_dx_countlimit_t *)entries;
    877         uint16_t leaf_limit = ext4_directory_dx_countlimit_get_limit(countlimit);
    878         uint16_t leaf_count = ext4_directory_dx_countlimit_get_count(countlimit);
    879 
     897            (ext4_directory_dx_countlimit_t *) entries;
     898       
     899        uint16_t leaf_limit =
     900            ext4_directory_dx_countlimit_get_limit(countlimit);
     901        uint16_t leaf_count =
     902            ext4_directory_dx_countlimit_get_count(countlimit);
     903       
    880904        /* Check if is necessary to split index block */
    881905        if (leaf_limit == leaf_count) {
    882 
    883                 unsigned int levels = dx_block - dx_blocks;
    884 
     906                size_t levels = dx_block - dx_blocks;
     907               
    885908                ext4_directory_dx_entry_t *root_entries =
    886                                         ((ext4_directory_dx_root_t *)dx_blocks[0].block->data)->entries;
    887 
     909                    ((ext4_directory_dx_root_t *) dx_blocks[0].block->data)->entries;
     910               
    888911                ext4_directory_dx_countlimit_t *root_countlimit =
    889                                 (ext4_directory_dx_countlimit_t *)root_entries;
     912                    (ext4_directory_dx_countlimit_t *) root_entries;
    890913                uint16_t root_limit =
    891                                 ext4_directory_dx_countlimit_get_limit(root_countlimit);
     914                    ext4_directory_dx_countlimit_get_limit(root_countlimit);
    892915                uint16_t root_count =
    893                                 ext4_directory_dx_countlimit_get_count(root_countlimit);
    894 
     916                    ext4_directory_dx_countlimit_get_count(root_countlimit);
     917               
    895918                /* Linux limitation */
    896                 if ((levels > 0) && (root_limit == root_count)) {
     919                if ((levels > 0) && (root_limit == root_count))
    897920                        return ENOSPC;
    898                 }
    899 
     921               
    900922                /* Add new block to directory */
    901923                uint32_t new_fblock;
    902924                uint32_t new_iblock;
    903                 rc =  ext4_filesystem_append_inode_block(
    904                                 inode_ref, &new_fblock, &new_iblock);
    905                 if (rc != EOK) {
     925                int rc = ext4_filesystem_append_inode_block(inode_ref,
     926                    &new_fblock, &new_iblock);
     927                if (rc != EOK)
    906928                        return rc;
    907                 }
    908 
     929               
    909930                /* load new block */
    910                 block_t * new_block;
     931                block_t *new_block;
    911932                rc = block_get(&new_block, inode_ref->fs->device,
    912                                 new_fblock, BLOCK_FLAGS_NOREAD);
    913                 if (rc != EOK) {
     933                    new_fblock, BLOCK_FLAGS_NOREAD);
     934                if (rc != EOK)
    914935                        return rc;
    915                 }
    916 
     936               
    917937                ext4_directory_dx_node_t *new_node = new_block->data;
    918938                ext4_directory_dx_entry_t *new_entries = new_node->entries;
    919 
    920                 uint32_t block_size = ext4_superblock_get_block_size(
    921                                 inode_ref->fs->superblock);
    922 
     939               
     940                uint32_t block_size =
     941                    ext4_superblock_get_block_size(inode_ref->fs->superblock);
     942               
    923943                /* Split leaf node */
    924944                if (levels > 0) {
    925 
    926945                        uint32_t count_left = leaf_count / 2;
    927946                        uint32_t count_right = leaf_count - count_left;
    928947                        uint32_t hash_right =
    929                                         ext4_directory_dx_entry_get_hash(entries + count_left);
    930 
     948                            ext4_directory_dx_entry_get_hash(entries + count_left);
     949                       
    931950                        /* Copy data to new node */
    932951                        memcpy((void *) new_entries, (void *) (entries + count_left),
    933                                         count_right * sizeof(ext4_directory_dx_entry_t));
    934 
     952                            count_right * sizeof(ext4_directory_dx_entry_t));
     953                       
    935954                        /* Initialize new node */
    936955                        ext4_directory_dx_countlimit_t *left_countlimit =
    937                                         (ext4_directory_dx_countlimit_t *)entries;
     956                            (ext4_directory_dx_countlimit_t *) entries;
    938957                        ext4_directory_dx_countlimit_t *right_countlimit =
    939                                         (ext4_directory_dx_countlimit_t *)new_entries;
    940 
     958                            (ext4_directory_dx_countlimit_t *) new_entries;
     959                       
    941960                        ext4_directory_dx_countlimit_set_count(left_countlimit, count_left);
    942961                        ext4_directory_dx_countlimit_set_count(right_countlimit, count_right);
    943 
    944                         uint32_t entry_space = block_size - sizeof(ext4_fake_directory_entry_t);
    945                         uint32_t node_limit = entry_space / sizeof(ext4_directory_dx_entry_t);
     962                       
     963                        uint32_t entry_space =
     964                            block_size - sizeof(ext4_fake_directory_entry_t);
     965                        uint32_t node_limit =
     966                            entry_space / sizeof(ext4_directory_dx_entry_t);
    946967                        ext4_directory_dx_countlimit_set_limit(right_countlimit, node_limit);
    947 
     968                       
    948969                        /* Which index block is target for new entry */
    949970                        uint32_t position_index = (dx_block->position - dx_block->entries);
    950971                        if (position_index >= count_left) {
    951 
    952972                                dx_block->block->dirty = true;
    953 
     973                               
    954974                                block_t *block_tmp = dx_block->block;
    955975                                dx_block->block = new_block;
    956                                 dx_block->position = new_entries + position_index - count_left;
     976                                dx_block->position =
     977                                    new_entries + position_index - count_left;
    957978                                dx_block->entries = new_entries;
    958 
     979                               
    959980                                new_block = block_tmp;
    960 
    961981                        }
    962 
     982                       
    963983                        /* Finally insert new entry */
    964984                        ext4_directory_dx_insert_entry(dx_blocks, hash_right, new_iblock);
    965 
     985                       
    966986                        return block_put(new_block);
    967 
    968987                } else {
    969 
    970988                        /* Create second level index */
    971 
     989                       
    972990                        /* Copy data from root to child block */
    973991                        memcpy((void *) new_entries, (void *) entries,
    974                                         leaf_count * sizeof(ext4_directory_dx_entry_t));
    975 
     992                            leaf_count * sizeof(ext4_directory_dx_entry_t));
     993                       
    976994                        ext4_directory_dx_countlimit_t *new_countlimit =
    977                                         (ext4_directory_dx_countlimit_t *)new_entries;
    978 
    979                         uint32_t entry_space = block_size - sizeof(ext4_fake_directory_entry_t);
    980                         uint32_t node_limit = entry_space / sizeof(ext4_directory_dx_entry_t);
     995                            (ext4_directory_dx_countlimit_t *) new_entries;
     996                       
     997                        uint32_t entry_space =
     998                            block_size - sizeof(ext4_fake_directory_entry_t);
     999                        uint32_t node_limit =
     1000                            entry_space / sizeof(ext4_directory_dx_entry_t);
    9811001                        ext4_directory_dx_countlimit_set_limit(new_countlimit, node_limit);
    982 
     1002                       
    9831003                        /* Set values in root node */
    9841004                        ext4_directory_dx_countlimit_t *new_root_countlimit =
    985                                         (ext4_directory_dx_countlimit_t *)entries;
    986 
     1005                            (ext4_directory_dx_countlimit_t *) entries;
     1006                       
    9871007                        ext4_directory_dx_countlimit_set_count(new_root_countlimit, 1);
    9881008                        ext4_directory_dx_entry_set_block(entries, new_iblock);
    989 
    990                         ((ext4_directory_dx_root_t *)dx_blocks[0].block->data)->info.indirect_levels = 1;
    991 
     1009                       
     1010                        ((ext4_directory_dx_root_t *)
     1011                            dx_blocks[0].block->data)->info.indirect_levels = 1;
     1012                       
    9921013                        /* Add new entry to the path */
    9931014                        dx_block = dx_blocks + 1;
     
    9961017                        dx_block->block = new_block;
    9971018                }
    998 
    999         }
    1000 
     1019        }
     1020       
    10011021        return EOK;
    10021022}
     
    10041024/** Add new entry to indexed directory
    10051025 *
    1006  * @param parent        directory i-node
    1007  * @param child         i-node to be referenced from directory entry
    1008  * @param name          name of new directory entry
    1009  * @return                      error code
     1026 * @param parent Directory i-node
     1027 * @param child  I-node to be referenced from directory entry
     1028 * @param name   Name of new directory entry
     1029 *
     1030 * @return Error code
     1031 *
    10101032 */
    10111033int ext4_directory_dx_add_entry(ext4_inode_ref_t *parent,
    1012                 ext4_inode_ref_t *child, const char *name)
    1013 {
    1014         int rc = EOK;
     1034    ext4_inode_ref_t *child, const char *name)
     1035{
    10151036        int rc2 = EOK;
    1016 
    1017         /* get direct block 0 (index root) */
     1037       
     1038        /* Get direct block 0 (index root) */
    10181039        uint32_t root_block_addr;
    1019         rc = ext4_filesystem_get_inode_data_block_index(parent, 0, &root_block_addr);
    1020         if (rc != EOK) {
    1021                 return rc;
    1022         }
    1023 
     1040        int rc = ext4_filesystem_get_inode_data_block_index(parent, 0,
     1041            &root_block_addr);
     1042        if (rc != EOK)
     1043                return rc;
     1044       
    10241045        ext4_filesystem_t *fs = parent->fs;
    1025 
     1046       
    10261047        block_t *root_block;
    1027         rc = block_get(&root_block, fs->device, root_block_addr, BLOCK_FLAGS_NONE);
    1028         if (rc != EOK) {
    1029                 return rc;
    1030         }
    1031 
     1048        rc = block_get(&root_block, fs->device, root_block_addr,
     1049            BLOCK_FLAGS_NONE);
     1050        if (rc != EOK)
     1051                return rc;
     1052       
    10321053        /* Initialize hinfo structure (mainly compute hash) */
    1033         uint32_t name_len = strlen(name);
     1054        uint32_t name_len = str_size(name);
    10341055        ext4_hash_info_t hinfo;
    1035         rc = ext4_directory_hinfo_init(&hinfo, root_block, fs->superblock, name_len, name);
     1056        rc = ext4_directory_hinfo_init(&hinfo, root_block, fs->superblock,
     1057            name_len, name);
    10361058        if (rc != EOK) {
    10371059                block_put(root_block);
    10381060                return EXT4_ERR_BAD_DX_DIR;
    10391061        }
    1040 
    1041         /* Hardcoded number 2 means maximum height of index tree defined in linux */
     1062       
     1063        /*
     1064         * Hardcoded number 2 means maximum height of index
     1065         * tree defined in Linux.
     1066         */
    10421067        ext4_directory_dx_block_t dx_blocks[2];
    1043         ext4_directory_dx_block_t *dx_block, *dx_it;
    1044         rc = ext4_directory_dx_get_leaf(&hinfo, parent, root_block, &dx_block, dx_blocks);
     1068        ext4_directory_dx_block_t *dx_block;
     1069        ext4_directory_dx_block_t *dx_it;
     1070       
     1071        rc = ext4_directory_dx_get_leaf(&hinfo, parent, root_block,
     1072            &dx_block, dx_blocks);
    10451073        if (rc != EOK) {
    10461074                rc = EXT4_ERR_BAD_DX_DIR;
    10471075                goto release_index;
    10481076        }
    1049 
    1050 
     1077       
    10511078        /* Try to insert to existing data block */
    1052         uint32_t leaf_block_idx = ext4_directory_dx_entry_get_block(dx_block->position);
     1079        uint32_t leaf_block_idx =
     1080            ext4_directory_dx_entry_get_block(dx_block->position);
    10531081        uint32_t leaf_block_addr;
    1054         rc = ext4_filesystem_get_inode_data_block_index(parent, leaf_block_idx, &leaf_block_addr);
    1055         if (rc != EOK) {
    1056                 goto release_index;
    1057         }
    1058 
    1059 
    1060         block_t *target_block;
    1061         rc = block_get(&target_block, fs->device, leaf_block_addr, BLOCK_FLAGS_NONE);
    1062         if (rc != EOK) {
    1063                 goto release_index;
    1064         }
    1065 
    1066         /* Check if insert operation passed */
    1067         rc = ext4_directory_try_insert_entry(fs->superblock, target_block, child, name, name_len);
    1068         if (rc == EOK) {
    1069                 goto release_target_index;
    1070         }
    1071 
    1072         /* Check if there is needed to split index node
    1073          * (and recursively also parent nodes)
    1074          */
     1082        rc = ext4_filesystem_get_inode_data_block_index(parent, leaf_block_idx,
     1083            &leaf_block_addr);
     1084        if (rc != EOK)
     1085                goto release_index;
     1086       
     1087        block_t *target_block;
     1088        rc = block_get(&target_block, fs->device, leaf_block_addr,
     1089            BLOCK_FLAGS_NONE);
     1090        if (rc != EOK)
     1091                goto release_index;
     1092       
     1093        /* Check if insert operation passed */
     1094        rc = ext4_directory_try_insert_entry(fs->superblock, target_block, child,
     1095            name, name_len);
     1096        if (rc == EOK)
     1097                goto release_target_index;
     1098       
     1099        /*
     1100         * Check if there is needed to split index node
     1101         * (and recursively also parent nodes)
     1102         */
    10751103        rc = ext4_directory_dx_split_index(parent, dx_blocks, dx_block);
    1076         if (rc != EOK) {
     1104        if (rc != EOK)
    10771105                goto release_target_index;
    1078         }
    1079 
     1106       
    10801107        /* Split entries to two blocks (includes sorting by hash value) */
    10811108        block_t *new_block = NULL;
    1082         rc = ext4_directory_dx_split_data(parent, &hinfo, target_block, dx_block, &new_block);
     1109        rc = ext4_directory_dx_split_data(parent, &hinfo, target_block,
     1110            dx_block, &new_block);
    10831111        if (rc != EOK) {
    10841112                rc2 = rc;
    10851113                goto release_target_index;
    10861114        }
    1087 
     1115       
    10881116        /* Where to save new entry */
    1089         uint32_t new_block_hash = ext4_directory_dx_entry_get_hash(dx_block->position + 1);
    1090         if (hinfo.hash >= new_block_hash) {
    1091                 rc = ext4_directory_try_insert_entry(fs->superblock, new_block, child, name, name_len);
    1092         } else {
    1093                 rc = ext4_directory_try_insert_entry(fs->superblock, target_block, child, name, name_len);
    1094         }
    1095 
     1117        uint32_t new_block_hash =
     1118            ext4_directory_dx_entry_get_hash(dx_block->position + 1);
     1119        if (hinfo.hash >= new_block_hash)
     1120                rc = ext4_directory_try_insert_entry(fs->superblock, new_block,
     1121                    child, name, name_len);
     1122        else
     1123                rc = ext4_directory_try_insert_entry(fs->superblock, target_block,
     1124                    child, name, name_len);
     1125       
    10961126        /* Cleanup */
    10971127        rc = block_put(new_block);
    1098         if (rc != EOK) {
    1099                 return rc;
    1100         }
    1101 
     1128        if (rc != EOK)
     1129                return rc;
     1130       
    11021131        /* Cleanup operations */
    1103 
     1132       
    11041133release_target_index:
    1105 
    11061134        rc2 = rc;
    1107 
     1135       
    11081136        rc = block_put(target_block);
    1109         if (rc != EOK) {
    1110                 return rc;
    1111         }
    1112 
     1137        if (rc != EOK)
     1138                return rc;
     1139       
    11131140release_index:
    1114 
    1115         if (rc != EOK) {
     1141        if (rc != EOK)
    11161142                rc2 = rc;
    1117         }
    1118 
     1143       
    11191144        dx_it = dx_blocks;
    1120 
     1145       
    11211146        while (dx_it <= dx_block) {
    11221147                rc = block_put(dx_it->block);
    1123                 if (rc != EOK) {
     1148                if (rc != EOK)
    11241149                        return rc;
    1125                 }
     1150               
    11261151                dx_it++;
    11271152        }
    1128 
     1153       
    11291154        return rc2;
    11301155}
    1131 
    11321156
    11331157/**
    11341158 * @}
    1135  */ 
     1159 */
Note: See TracChangeset for help on using the changeset viewer.