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

Changeset 38542dc in mainline


Ignore:
Timestamp:
2012-08-12T18:36:10Z (9 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
49505fe
Parents:
b08e7970
Message:

ext4 code review and coding style cleanup

Location:
uspace
Files:
32 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/testwrit/testwrit.c

    rb08e7970 r38542dc  
    3131 */
    3232
    33 
    3433#include <stdio.h>
    3534#include <unistd.h>
    3635
    37 #define BUF_SIZE 1024
     36#define BUF_SIZE  1024
    3837
    39 int main(int argc, char **argv)
     38int main(int argc, char *argv[])
    4039{
    41 
    4240        char buffer[BUF_SIZE];
    4341        uint64_t iterations, i;
     
    4745        /* Prepare some example data */
    4846        memset(buffer, 0xcafebabe, BUF_SIZE);
    49 
     47       
    5048        if (argc != 3) {
    5149                printf("syntax: testwrit <iterations> <target file>\n");
    5250                return 1;
    5351        }
    54 
     52       
    5553        char *end;
    5654        iterations = strtoul(argv[1], &end, 10);
    5755        file_name = argv[2];
    58 
     56       
    5957        /* Open target file */
    6058        file = fopen(file_name, "a");
     
    7068       
    7169        fclose(file);
    72 
     70       
    7371        return 0;
    7472}
    75 
    7673
    7774/**
  • uspace/lib/ext4/Makefile

    rb08e7970 r38542dc  
    2929USPACE_PREFIX = ../..
    3030LIBRARY = libext4
    31 EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBPOSIX_PREFIX)
    32 LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBPOSIX_PREFIX)/libposix.a
     31EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX)
     32LIBS = $(LIBBLOCK_PREFIX)/libblock.a
    3333
    3434SOURCES = \
     
    4545        libext4_inode.c \
    4646        libext4_superblock.c
    47        
    4847
    4948include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/ext4/libext4.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_H_
     
    4949
    5050#include <stdio.h>
    51 #define EXT4FS_DBG(format, ...) {printf("ext4fs: %s: " format "\n", __FUNCTION__, ##__VA_ARGS__);}
     51#define EXT4FS_DBG(format, ...) \
     52        printf("ext4fs: %s: " format "\n", \
     53            __FUNCTION__, ##__VA_ARGS__) \
    5254
    5355#endif
  • uspace/lib/ext4/libext4_balloc.c

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        libext4_balloc.c
    35  * @brief       Physical block allocator.
     33 * @file  libext4_balloc.c
     34 * @brief Physical block allocator.
    3635 */
    3736
     
    4241/** Compute number of block group from block address.
    4342 *
    44  * @param sb                    superblock pointer
    45  * @param block_addr    absolute address of block
    46  * @return                              block group index
     43 * @param sb         Superblock pointer.
     44 * @param block_addr Absolute address of block.
     45 *
     46 * @return Block group index
     47 *
    4748 */
    4849static uint32_t ext4_balloc_get_bgid_of_block(ext4_superblock_t *sb,
    49                 uint32_t block_addr)
     50    uint32_t block_addr)
    5051{
    51         uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
    52         uint32_t first_block = ext4_superblock_get_first_data_block(sb);
    53 
     52        uint32_t blocks_per_group =
     53            ext4_superblock_get_blocks_per_group(sb);
     54        uint32_t first_block =
     55            ext4_superblock_get_first_data_block(sb);
     56       
    5457        /* First block == 0 or 1 */
    55         if (first_block == 0) {
     58        if (first_block == 0)
    5659                return block_addr / blocks_per_group;
    57         } else {
     60        else
    5861                return (block_addr - 1) / blocks_per_group;
    59         }
    6062}
    6163
    6264/** Free block.
    6365 *
    64  * @param inode_ref                     inode, where the block is allocated
    65  * @param block_addr            absolute block address to free
    66  * @return                                      error code
     66 * @param inode_ref  Inode, where the block is allocated
     67 * @param block_addr Absolute block address to free
     68 *
     69 * @return Error code
     70 *
    6771 */
    6872int ext4_balloc_free_block(ext4_inode_ref_t *inode_ref, uint32_t block_addr)
    6973{
    70         int rc;
    71 
    7274        ext4_filesystem_t *fs = inode_ref->fs;
    7375        ext4_superblock_t *sb = fs->superblock;
    74 
     76       
    7577        /* Compute indexes */
    7678        uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, block_addr);
    7779        uint32_t index_in_group =
    78                         ext4_filesystem_blockaddr2_index_in_group(sb, block_addr);
    79 
     80            ext4_filesystem_blockaddr2_index_in_group(sb, block_addr);
     81       
    8082        /* Load block group reference */
    8183        ext4_block_group_ref_t *bg_ref;
    82         rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
    83         if (rc != EOK) {
    84                 return rc;
    85         }
    86 
     84        int rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
     85        if (rc != EOK)
     86                return rc;
     87       
    8788        /* Load block with bitmap */
    88         uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
    89                         bg_ref->block_group, sb);
     89        uint32_t bitmap_block_addr =
     90            ext4_block_group_get_block_bitmap(bg_ref->block_group, sb);
    9091        block_t *bitmap_block;
    9192        rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
    92         if (rc != EOK) {
    93                 return rc;
    94         }
    95 
     93        if (rc != EOK)
     94                return rc;
     95       
    9696        /* Modify bitmap */
    9797        ext4_bitmap_free_bit(bitmap_block->data, index_in_group);
    9898        bitmap_block->dirty = true;
    99 
    100 
     99       
    101100        /* Release block with bitmap */
    102101        rc = block_put(bitmap_block);
     
    106105                return rc;
    107106        }
    108 
     107       
    109108        uint32_t block_size = ext4_superblock_get_block_size(sb);
    110 
     109       
    111110        /* Update superblock free blocks count */
    112         uint32_t sb_free_blocks = ext4_superblock_get_free_blocks_count(sb);
     111        uint32_t sb_free_blocks =
     112            ext4_superblock_get_free_blocks_count(sb);
    113113        sb_free_blocks++;
    114114        ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
    115 
     115       
    116116        /* Update inode blocks count */
    117         uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);
     117        uint64_t ino_blocks =
     118            ext4_inode_get_blocks_count(sb, inode_ref->inode);
    118119        ino_blocks -= block_size / EXT4_INODE_BLOCK_SIZE;
    119120        ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
    120121        inode_ref->dirty = true;
    121 
     122       
    122123        /* Update block group free blocks count */
    123         uint32_t free_blocks = ext4_block_group_get_free_blocks_count(
    124                         bg_ref->block_group, sb);
     124        uint32_t free_blocks =
     125            ext4_block_group_get_free_blocks_count(bg_ref->block_group, sb);
    125126        free_blocks++;
    126127        ext4_block_group_set_free_blocks_count(bg_ref->block_group,
    127                         sb, free_blocks);
     128            sb, free_blocks);
    128129        bg_ref->dirty = true;
    129 
     130       
    130131        /* Release block group reference */
    131132        rc = ext4_filesystem_put_block_group_ref(bg_ref);
    132         if (rc != EOK) {
    133                 return rc;
    134         }
    135 
     133        if (rc != EOK)
     134                return rc;
     135       
    136136        return EOK;
    137137}
    138138
    139 
    140139/** Free continuous set of blocks.
    141140 *
    142  * @param inode_ref                     inode, where the blocks are allocated
    143  * @param first                         first block to release
    144  * @param count                         number of blocks to release
     141 * @param inode_ref Inode, where the blocks are allocated
     142 * @param first     First block to release
     143 * @param count     Number of blocks to release
     144 *
    145145 */
    146146int ext4_balloc_free_blocks(ext4_inode_ref_t *inode_ref,
    147                 uint32_t first, uint32_t count)
     147    uint32_t first, uint32_t count)
    148148{
    149         int rc;
    150 
    151149        ext4_filesystem_t *fs = inode_ref->fs;
    152150        ext4_superblock_t *sb = fs->superblock;
    153 
     151       
    154152        /* Compute indexes */
    155153        uint32_t block_group_first =
    156                         ext4_balloc_get_bgid_of_block(sb, first);
     154            ext4_balloc_get_bgid_of_block(sb, first);
    157155        uint32_t block_group_last =
    158                         ext4_balloc_get_bgid_of_block(sb, first + count - 1);
    159 
     156            ext4_balloc_get_bgid_of_block(sb, first + count - 1);
     157       
    160158        assert(block_group_first == block_group_last);
    161 
     159       
    162160        /* Load block group reference */
    163161        ext4_block_group_ref_t *bg_ref;
    164         rc = ext4_filesystem_get_block_group_ref(fs, block_group_first, &bg_ref);
    165         if (rc != EOK) {
    166                 return rc;
    167         }
    168 
     162        int rc = ext4_filesystem_get_block_group_ref(fs, block_group_first, &bg_ref);
     163        if (rc != EOK)
     164                return rc;
     165       
    169166        uint32_t index_in_group_first =
    170                         ext4_filesystem_blockaddr2_index_in_group(sb, first);
    171 
    172 
     167            ext4_filesystem_blockaddr2_index_in_group(sb, first);
     168       
    173169        /* Load block with bitmap */
    174         uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
    175                         bg_ref->block_group, sb);
    176 
     170        uint32_t bitmap_block_addr =
     171            ext4_block_group_get_block_bitmap(bg_ref->block_group, sb);
     172       
    177173        block_t *bitmap_block;
    178174        rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
    179         if (rc != EOK) {
    180                 return rc;
    181         }
    182 
     175        if (rc != EOK)
     176                return rc;
     177       
    183178        /* Modify bitmap */
    184179        ext4_bitmap_free_bits(bitmap_block->data, index_in_group_first, count);
    185180        bitmap_block->dirty = true;
    186 
     181       
    187182        /* Release block with bitmap */
    188183        rc = block_put(bitmap_block);
     
    192187                return rc;
    193188        }
    194 
     189       
    195190        uint32_t block_size = ext4_superblock_get_block_size(sb);
    196 
     191       
    197192        /* Update superblock free blocks count */
    198         uint32_t sb_free_blocks = ext4_superblock_get_free_blocks_count(sb);
     193        uint32_t sb_free_blocks =
     194            ext4_superblock_get_free_blocks_count(sb);
    199195        sb_free_blocks += count;
    200196        ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
    201 
     197       
    202198        /* Update inode blocks count */
    203         uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);
     199        uint64_t ino_blocks =
     200            ext4_inode_get_blocks_count(sb, inode_ref->inode);
    204201        ino_blocks -= count * (block_size / EXT4_INODE_BLOCK_SIZE);
    205202        ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
    206203        inode_ref->dirty = true;
    207 
     204       
    208205        /* Update block group free blocks count */
    209         uint32_t free_blocks = ext4_block_group_get_free_blocks_count(
    210                         bg_ref->block_group, sb);
     206        uint32_t free_blocks =
     207            ext4_block_group_get_free_blocks_count(bg_ref->block_group, sb);
    211208        free_blocks += count;
    212209        ext4_block_group_set_free_blocks_count(bg_ref->block_group,
    213                         sb, free_blocks);
     210            sb, free_blocks);
    214211        bg_ref->dirty = true;
    215 
     212       
    216213        /* Release block group reference */
    217214        rc = ext4_filesystem_put_block_group_ref(bg_ref);
    218         if (rc != EOK) {
    219                 return rc;
    220         }
    221 
     215        if (rc != EOK)
     216                return rc;
     217       
    222218        return EOK;
    223219}
     
    225221/** Compute first block for data in block group.
    226222 *
    227  * @param sb            pointer to superblock
    228  * @param bg            pointer to block group
    229  * @param bgid          index of block group
    230  * @return                      absolute block index of first block
    231  */
    232 uint32_t ext4_balloc_get_first_data_block_in_group(
    233                 ext4_superblock_t *sb, ext4_block_group_ref_t *bg_ref)
     223 * @param sb   Pointer to superblock
     224 * @param bg   Pointer to block group
     225 * @param bgid Index of block group
     226 *
     227 * @return Absolute block index of first block
     228 *
     229 */
     230uint32_t ext4_balloc_get_first_data_block_in_group(ext4_superblock_t *sb,
     231    ext4_block_group_ref_t *bg_ref)
    234232{
    235233        uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
    236         uint32_t inode_table_first_block = ext4_block_group_get_inode_table_first_block(
    237                         bg_ref->block_group, sb);
     234        uint32_t inode_table_first_block =
     235            ext4_block_group_get_inode_table_first_block(bg_ref->block_group, sb);
    238236        uint16_t inode_table_item_size = ext4_superblock_get_inode_size(sb);
    239237        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
    240238        uint32_t block_size = ext4_superblock_get_block_size(sb);
    241239        uint32_t inode_table_bytes;
    242 
     240       
    243241        if (bg_ref->index < block_group_count - 1) {
    244242                inode_table_bytes = inodes_per_group * inode_table_item_size;
    245243        } else {
    246                 /* last block group could be smaller */
     244                /* Last block group could be smaller */
    247245                uint32_t inodes_count_total = ext4_superblock_get_inodes_count(sb);
    248246                inode_table_bytes =
    249                                 (inodes_count_total - ((block_group_count - 1) * inodes_per_group))
    250                                 * inode_table_item_size;
    251         }
    252 
     247                    (inodes_count_total - ((block_group_count - 1) * inodes_per_group)) *
     248                    inode_table_item_size;
     249        }
     250       
    253251        uint32_t inode_table_blocks = inode_table_bytes / block_size;
    254 
    255         if (inode_table_bytes % block_size) {
     252       
     253        if (inode_table_bytes % block_size)
    256254                inode_table_blocks++;
    257         }
    258 
     255       
    259256        return inode_table_first_block + inode_table_blocks;
    260257}
     
    262259/** Compute 'goal' for allocation algorithm.
    263260 *
    264  * @param inode_ref             reference to inode, to allocate block for
    265  * @return                              goal block number
     261 * @param inode_ref Reference to inode, to allocate block for
     262 *
     263 * @return Goal block number
     264 *
    266265 */
    267266static uint32_t ext4_balloc_find_goal(ext4_inode_ref_t *inode_ref)
    268267{
    269         int rc;
    270268        uint32_t goal = 0;
    271 
     269       
    272270        ext4_superblock_t *sb = inode_ref->fs->superblock;
    273 
     271       
    274272        uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
    275273        uint32_t block_size = ext4_superblock_get_block_size(sb);
    276274        uint32_t inode_block_count = inode_size / block_size;
    277 
    278         if (inode_size % block_size != 0) {
     275       
     276        if (inode_size % block_size != 0)
    279277                inode_block_count++;
    280         }
    281 
     278       
    282279        /* If inode has some blocks, get last block address + 1 */
    283280        if (inode_block_count > 0) {
    284 
    285                 rc = ext4_filesystem_get_inode_data_block_index(inode_ref, inode_block_count - 1, &goal);
    286                 if (rc != EOK) {
     281                int rc = ext4_filesystem_get_inode_data_block_index(inode_ref,
     282                    inode_block_count - 1, &goal);
     283                if (rc != EOK)
    287284                        return 0;
    288                 }
    289 
     285               
    290286                if (goal != 0) {
    291287                        goal++;
    292288                        return goal;
    293289                }
    294 
    295                 /* if goal == 0, sparse file -> continue */
    296         }
    297 
     290               
     291                /* If goal == 0, sparse file -> continue */
     292        }
     293       
    298294        /* Identify block group of inode */
    299295        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
    300296        uint32_t block_group = (inode_ref->index - 1) / inodes_per_group;
    301297        block_size = ext4_superblock_get_block_size(sb);
    302 
     298       
    303299        /* Load block group reference */
    304300        ext4_block_group_ref_t *bg_ref;
    305         rc = ext4_filesystem_get_block_group_ref(inode_ref->fs, block_group, &bg_ref);
    306         if (rc != EOK) {
     301        int rc = ext4_filesystem_get_block_group_ref(inode_ref->fs,
     302            block_group, &bg_ref);
     303        if (rc != EOK)
    307304                return 0;
    308         }
    309 
     305       
    310306        /* Compute indexes */
    311307        uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
    312         uint32_t inode_table_first_block = ext4_block_group_get_inode_table_first_block(
    313                         bg_ref->block_group, sb);
     308        uint32_t inode_table_first_block =
     309            ext4_block_group_get_inode_table_first_block(bg_ref->block_group, sb);
    314310        uint16_t inode_table_item_size = ext4_superblock_get_inode_size(sb);
    315311        uint32_t inode_table_bytes;
    316 
     312       
    317313        /* Check for last block group */
    318314        if (block_group < block_group_count - 1) {
    319315                inode_table_bytes = inodes_per_group * inode_table_item_size;
    320316        } else {
    321                 /* last block group could be smaller */
     317                /* Last block group could be smaller */
    322318                uint32_t inodes_count_total = ext4_superblock_get_inodes_count(sb);
    323319                inode_table_bytes =
    324                                 (inodes_count_total - ((block_group_count - 1) * inodes_per_group))
    325                                 * inode_table_item_size;
    326         }
    327 
     320                    (inodes_count_total - ((block_group_count - 1) * inodes_per_group)) *
     321                    inode_table_item_size;
     322        }
     323       
    328324        uint32_t inode_table_blocks = inode_table_bytes / block_size;
    329 
    330         if (inode_table_bytes % block_size) {
     325       
     326        if (inode_table_bytes % block_size)
    331327                inode_table_blocks++;
    332         }
    333 
     328       
    334329        goal = inode_table_first_block + inode_table_blocks;
    335 
     330       
    336331        ext4_filesystem_put_block_group_ref(bg_ref);
    337 
     332       
    338333        return goal;
    339334}
     
    341336/** Data block allocation algorithm.
    342337 *
    343  * @param inode_ref             inode to allocate block for
    344  * @param fblock                allocated block address
    345  * @return                              error code
    346  */
    347 int ext4_balloc_alloc_block(
    348                 ext4_inode_ref_t *inode_ref, uint32_t *fblock)
     338 * @param inode_ref Inode to allocate block for
     339 * @param fblock    Allocated block address
     340 *
     341 * @return Error code
     342 *
     343 */
     344int ext4_balloc_alloc_block(ext4_inode_ref_t *inode_ref, uint32_t *fblock)
    349345{
    350         int rc;
    351346        uint32_t allocated_block = 0;
    352 
     347       
    353348        uint32_t bitmap_block_addr;
    354349        block_t *bitmap_block;
    355350        uint32_t rel_block_idx = 0;
    356 
     351       
    357352        /* Find GOAL */
    358353        uint32_t goal = ext4_balloc_find_goal(inode_ref);
     
    361356                return ENOSPC;
    362357        }
    363 
     358       
    364359        ext4_superblock_t *sb = inode_ref->fs->superblock;
    365 
     360       
    366361        /* Load block group number for goal and relative index */
    367362        uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, goal);
    368363        uint32_t index_in_group =
    369                         ext4_filesystem_blockaddr2_index_in_group(sb, goal);
    370 
    371 
     364            ext4_filesystem_blockaddr2_index_in_group(sb, goal);
     365       
    372366        /* Load block group reference */
    373367        ext4_block_group_ref_t *bg_ref;
    374         rc = ext4_filesystem_get_block_group_ref(inode_ref->fs, block_group, &bg_ref);
    375         if (rc != EOK) {
    376                 return rc;
    377         }
    378 
     368        int rc = ext4_filesystem_get_block_group_ref(inode_ref->fs,
     369            block_group, &bg_ref);
     370        if (rc != EOK)
     371                return rc;
     372       
    379373        /* Compute indexes */
    380374        uint32_t first_in_group =
    381                         ext4_balloc_get_first_data_block_in_group(sb, bg_ref);
    382 
    383         uint32_t first_in_group_index = ext4_filesystem_blockaddr2_index_in_group(
    384                         sb, first_in_group);
    385 
    386         if (index_in_group < first_in_group_index) {
     375            ext4_balloc_get_first_data_block_in_group(sb, bg_ref);
     376       
     377        uint32_t first_in_group_index =
     378            ext4_filesystem_blockaddr2_index_in_group(sb, first_in_group);
     379       
     380        if (index_in_group < first_in_group_index)
    387381                index_in_group = first_in_group_index;
    388         }
    389 
     382       
    390383        /* Load block with bitmap */
    391         bitmap_block_addr = ext4_block_group_get_block_bitmap(
    392                         bg_ref->block_group, sb);
    393 
     384        bitmap_block_addr =
     385            ext4_block_group_get_block_bitmap(bg_ref->block_group, sb);
     386       
    394387        rc = block_get(&bitmap_block, inode_ref->fs->device,
    395                         bitmap_block_addr, BLOCK_FLAGS_NONE);
     388            bitmap_block_addr, BLOCK_FLAGS_NONE);
    396389        if (rc != EOK) {
    397390                ext4_filesystem_put_block_group_ref(bg_ref);
    398391                return rc;
    399392        }
    400 
     393       
    401394        /* Check if goal is free */
    402395        if (ext4_bitmap_is_free_bit(bitmap_block->data, index_in_group)) {
     
    408401                        return rc;
    409402                }
    410 
    411                 allocated_block = ext4_filesystem_index_in_group2blockaddr(
    412                                                         sb, index_in_group, block_group);
    413 
     403               
     404                allocated_block =
     405                    ext4_filesystem_index_in_group2blockaddr(sb, index_in_group,
     406                    block_group);
     407               
    414408                goto success;
    415 
    416         }
    417 
    418         uint32_t blocks_in_group = ext4_superblock_get_blocks_in_group(sb, block_group);
    419 
     409        }
     410       
     411        uint32_t blocks_in_group =
     412            ext4_superblock_get_blocks_in_group(sb, block_group);
     413       
    420414        uint32_t end_idx = (index_in_group + 63) & ~63;
    421         if (end_idx > blocks_in_group) {
     415        if (end_idx > blocks_in_group)
    422416                end_idx = blocks_in_group;
    423         }
    424 
     417       
    425418        /* Try to find free block near to goal */
    426         for (uint32_t tmp_idx = index_in_group + 1; tmp_idx < end_idx; ++tmp_idx) {
     419        for (uint32_t tmp_idx = index_in_group + 1; tmp_idx < end_idx;
     420            ++tmp_idx) {
    427421                if (ext4_bitmap_is_free_bit(bitmap_block->data, tmp_idx)) {
    428 
    429422                        ext4_bitmap_set_bit(bitmap_block->data, tmp_idx);
    430423                        bitmap_block->dirty = true;
    431424                        rc = block_put(bitmap_block);
    432                         if (rc != EOK) {
     425                        if (rc != EOK)
    433426                                return rc;
    434                         }
    435 
    436                         allocated_block = ext4_filesystem_index_in_group2blockaddr(
    437                                         sb, tmp_idx, block_group);
    438 
     427                       
     428                        allocated_block =
     429                            ext4_filesystem_index_in_group2blockaddr(sb, tmp_idx,
     430                            block_group);
     431                       
    439432                        goto success;
    440433                }
    441 
    442         }
    443 
     434        }
     435       
    444436        /* Find free BYTE in bitmap */
    445         rc = ext4_bitmap_find_free_byte_and_set_bit(bitmap_block->data, index_in_group, &rel_block_idx, blocks_in_group);
     437        rc = ext4_bitmap_find_free_byte_and_set_bit(bitmap_block->data,
     438            index_in_group, &rel_block_idx, blocks_in_group);
    446439        if (rc == EOK) {
    447440                bitmap_block->dirty = true;
    448441                rc = block_put(bitmap_block);
    449                 if (rc != EOK) {
     442                if (rc != EOK)
    450443                        return rc;
    451                 }
    452 
    453                 allocated_block = ext4_filesystem_index_in_group2blockaddr(
    454                                 sb, rel_block_idx, block_group);
    455 
     444               
     445                allocated_block =
     446                    ext4_filesystem_index_in_group2blockaddr(sb, rel_block_idx,
     447                    block_group);
     448               
    456449                goto success;
    457450        }
    458 
     451       
    459452        /* Find free bit in bitmap */
    460         rc = ext4_bitmap_find_free_bit_and_set(bitmap_block->data, index_in_group, &rel_block_idx, blocks_in_group);
     453        rc = ext4_bitmap_find_free_bit_and_set(bitmap_block->data,
     454            index_in_group, &rel_block_idx, blocks_in_group);
    461455        if (rc == EOK) {
    462456                bitmap_block->dirty = true;
    463457                rc = block_put(bitmap_block);
    464                 if (rc != EOK) {
     458                if (rc != EOK)
    465459                        return rc;
    466                 }
    467 
    468                 allocated_block = ext4_filesystem_index_in_group2blockaddr(
    469                                 sb, rel_block_idx, block_group);
    470 
     460               
     461                allocated_block =
     462                    ext4_filesystem_index_in_group2blockaddr(sb, rel_block_idx,
     463                    block_group);
     464               
    471465                goto success;
    472466        }
    473 
     467       
    474468        /* No free block found yet */
    475469        block_put(bitmap_block);
    476470        ext4_filesystem_put_block_group_ref(bg_ref);
    477 
     471       
    478472        /* Try other block groups */
    479473        uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
    480 
     474       
    481475        uint32_t bgid = (block_group + 1) % block_group_count;
    482476        uint32_t count = block_group_count;
    483 
     477       
    484478        while (count > 0) {
    485                 rc = ext4_filesystem_get_block_group_ref(inode_ref->fs, bgid, &bg_ref);
    486                 if (rc != EOK) {
     479                rc = ext4_filesystem_get_block_group_ref(inode_ref->fs, bgid,
     480                    &bg_ref);
     481                if (rc != EOK)
    487482                        return rc;
    488                 }
    489 
     483               
    490484                /* Load block with bitmap */
    491                 bitmap_block_addr = ext4_block_group_get_block_bitmap(
    492                                 bg_ref->block_group, sb);
    493 
    494                 rc = block_get(&bitmap_block, inode_ref->fs->device, bitmap_block_addr, 0);
     485                bitmap_block_addr =
     486                    ext4_block_group_get_block_bitmap(bg_ref->block_group, sb);
     487               
     488                rc = block_get(&bitmap_block, inode_ref->fs->device,
     489                    bitmap_block_addr, 0);
    495490                if (rc != EOK) {
    496491                        ext4_filesystem_put_block_group_ref(bg_ref);
    497492                        return rc;
    498493                }
    499 
     494               
    500495                /* Compute indexes */
    501                 first_in_group = ext4_balloc_get_first_data_block_in_group(
    502                                 sb, bg_ref);
    503                 index_in_group = ext4_filesystem_blockaddr2_index_in_group(sb,
    504                                                 first_in_group);
     496                first_in_group =
     497                    ext4_balloc_get_first_data_block_in_group(sb, bg_ref);
     498                index_in_group =
     499                    ext4_filesystem_blockaddr2_index_in_group(sb, first_in_group);
    505500                blocks_in_group = ext4_superblock_get_blocks_in_group(sb, bgid);
    506 
    507                 first_in_group_index = ext4_filesystem_blockaddr2_index_in_group(
    508                         sb, first_in_group);
    509 
    510                 if (index_in_group < first_in_group_index) {
     501               
     502                first_in_group_index =
     503                    ext4_filesystem_blockaddr2_index_in_group(sb, first_in_group);
     504               
     505                if (index_in_group < first_in_group_index)
    511506                        index_in_group = first_in_group_index;
    512                 }
    513 
     507               
    514508                /* Try to find free byte in bitmap */
    515509                rc = ext4_bitmap_find_free_byte_and_set_bit(bitmap_block->data,
    516                                 index_in_group, &rel_block_idx, blocks_in_group);
     510                    index_in_group, &rel_block_idx, blocks_in_group);
    517511                if (rc == EOK) {
    518512                        bitmap_block->dirty = true;
    519513                        rc = block_put(bitmap_block);
    520                         if (rc != EOK) {
     514                        if (rc != EOK)
    521515                                return rc;
    522                         }
    523 
    524                         allocated_block = ext4_filesystem_index_in_group2blockaddr(
    525                                         sb, rel_block_idx, bgid);
    526 
     516                       
     517                        allocated_block =
     518                            ext4_filesystem_index_in_group2blockaddr(sb, rel_block_idx,
     519                            bgid);
     520                       
    527521                        goto success;
    528522                }
    529 
     523               
    530524                /* Try to find free bit in bitmap */
    531                 rc = ext4_bitmap_find_free_bit_and_set(bitmap_block->data, index_in_group, &rel_block_idx, blocks_in_group);
     525                rc = ext4_bitmap_find_free_bit_and_set(bitmap_block->data,
     526                    index_in_group, &rel_block_idx, blocks_in_group);
    532527                if (rc == EOK) {
    533528                        bitmap_block->dirty = true;
    534529                        rc = block_put(bitmap_block);
    535                         if (rc != EOK) {
     530                        if (rc != EOK)
    536531                                return rc;
    537                         }
    538 
    539                         allocated_block = ext4_filesystem_index_in_group2blockaddr(
    540                                         sb, rel_block_idx, bgid);
    541 
     532                       
     533                        allocated_block =
     534                            ext4_filesystem_index_in_group2blockaddr(sb, rel_block_idx,
     535                            bgid);
     536                       
    542537                        goto success;
    543538                }
    544 
     539               
    545540                block_put(bitmap_block);
    546541                ext4_filesystem_put_block_group_ref(bg_ref);
    547 
     542               
    548543                /* Goto next group */
    549544                bgid = (bgid + 1) % block_group_count;
    550545                count--;
    551546        }
    552 
     547       
    553548        return ENOSPC;
    554 
     549       
    555550success:
    556         ;       /* Empty command - because of syntax */
     551        /* Empty command - because of syntax */
     552        ;
    557553       
    558554        uint32_t block_size = ext4_superblock_get_block_size(sb);
    559 
     555       
    560556        /* Update superblock free blocks count */
    561557        uint32_t sb_free_blocks = ext4_superblock_get_free_blocks_count(sb);
    562558        sb_free_blocks--;
    563559        ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
    564 
     560       
    565561        /* Update inode blocks (different block size!) count */
    566         uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);
     562        uint64_t ino_blocks =
     563            ext4_inode_get_blocks_count(sb, inode_ref->inode);
    567564        ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE;
    568565        ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
    569566        inode_ref->dirty = true;
    570 
     567       
    571568        /* Update block group free blocks count */
    572         uint32_t bg_free_blocks = ext4_block_group_get_free_blocks_count(
    573                         bg_ref->block_group, sb);
     569        uint32_t bg_free_blocks =
     570            ext4_block_group_get_free_blocks_count(bg_ref->block_group, sb);
    574571        bg_free_blocks--;
    575         ext4_block_group_set_free_blocks_count(bg_ref->block_group, sb, bg_free_blocks);
     572        ext4_block_group_set_free_blocks_count(bg_ref->block_group, sb,
     573            bg_free_blocks);
    576574        bg_ref->dirty = true;
    577 
     575       
    578576        ext4_filesystem_put_block_group_ref(bg_ref);
    579 
     577       
    580578        *fblock = allocated_block;
    581579        return EOK;
     
    584582/** Try to allocate concrete block.
    585583 *
    586  * @param inode_ref             inode to allocate block for
    587  * @param fblock                block address to allocate
    588  * @param free                  output value - if target block is free
    589  * @return                              error code
    590  */
    591 int ext4_balloc_try_alloc_block(ext4_inode_ref_t *inode_ref,
    592                 uint32_t fblock, bool *free)
     584 * @param inode_ref Inode to allocate block for
     585 * @param fblock    Block address to allocate
     586 * @param free      Output value - if target block is free
     587 *
     588 * @return Error code
     589 *
     590 */
     591int ext4_balloc_try_alloc_block(ext4_inode_ref_t *inode_ref, uint32_t fblock,
     592    bool *free)
    593593{
    594594        int rc = EOK;
    595 
     595       
    596596        ext4_filesystem_t *fs = inode_ref->fs;
    597597        ext4_superblock_t *sb = fs->superblock;
    598 
     598       
    599599        /* Compute indexes */
    600600        uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, fblock);
    601601        uint32_t index_in_group =
    602                         ext4_filesystem_blockaddr2_index_in_group(sb, fblock);
    603 
     602            ext4_filesystem_blockaddr2_index_in_group(sb, fblock);
     603       
    604604        /* Load block group reference */
    605605        ext4_block_group_ref_t *bg_ref;
    606606        rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
    607         if (rc != EOK) {
    608                 return rc;
    609         }
    610 
     607        if (rc != EOK)
     608                return rc;
     609       
    611610        /* Load block with bitmap */
    612         uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
    613                         bg_ref->block_group, sb);
     611        uint32_t bitmap_block_addr =
     612            ext4_block_group_get_block_bitmap(bg_ref->block_group, sb);
    614613        block_t *bitmap_block;
    615614        rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
    616         if (rc != EOK) {
    617                 return rc;
    618         }
    619 
     615        if (rc != EOK)
     616                return rc;
     617       
    620618        /* Check if block is free */
    621619        *free = ext4_bitmap_is_free_bit(bitmap_block->data, index_in_group);
    622 
     620       
    623621        /* Allocate block if possible */
    624622        if (*free) {
     
    626624                bitmap_block->dirty = true;
    627625        }
    628 
     626       
    629627        /* Release block with bitmap */
    630628        rc = block_put(bitmap_block);
     
    634632                return rc;
    635633        }
    636 
     634       
    637635        /* If block is not free, return */
    638         if (!(*free)) {
     636        if (!(*free))
    639637                goto terminate;
    640         }
    641 
     638       
    642639        uint32_t block_size = ext4_superblock_get_block_size(sb);
    643 
     640       
    644641        /* Update superblock free blocks count */
    645642        uint32_t sb_free_blocks = ext4_superblock_get_free_blocks_count(sb);
    646643        sb_free_blocks--;
    647644        ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
    648 
     645       
    649646        /* Update inode blocks count */
    650         uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);
     647        uint64_t ino_blocks =
     648            ext4_inode_get_blocks_count(sb, inode_ref->inode);
    651649        ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE;
    652650        ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
    653651        inode_ref->dirty = true;
    654 
     652       
    655653        /* Update block group free blocks count */
    656         uint32_t free_blocks = ext4_block_group_get_free_blocks_count(
    657                         bg_ref->block_group, sb);
     654        uint32_t free_blocks =
     655            ext4_block_group_get_free_blocks_count(bg_ref->block_group, sb);
    658656        free_blocks--;
    659657        ext4_block_group_set_free_blocks_count(bg_ref->block_group,
    660                         sb, free_blocks);
     658            sb, free_blocks);
    661659        bg_ref->dirty = true;
    662 
     660       
    663661terminate:
    664 
    665         rc = ext4_filesystem_put_block_group_ref(bg_ref);
    666         if (rc != EOK) {
    667                 return rc;
    668         }
    669 
    670         return rc;
     662        return ext4_filesystem_put_block_group_ref(bg_ref);
    671663}
    672664
    673665/**
    674666 * @}
    675  */ 
     667 */
  • uspace/lib/ext4/libext4_balloc.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_BALLOC_H_
     
    3838
    3939extern int ext4_balloc_free_block(ext4_inode_ref_t *, uint32_t);
    40 extern int ext4_balloc_free_blocks(ext4_inode_ref_t *,
    41                 uint32_t , uint32_t);
    42 extern uint32_t ext4_balloc_get_first_data_block_in_group(
    43                 ext4_superblock_t *, ext4_block_group_ref_t *);
     40extern int ext4_balloc_free_blocks(ext4_inode_ref_t *, uint32_t, uint32_t);
     41extern uint32_t ext4_balloc_get_first_data_block_in_group(ext4_superblock_t *,
     42    ext4_block_group_ref_t *);
    4443extern int ext4_balloc_alloc_block(ext4_inode_ref_t *, uint32_t *);
    4544extern int ext4_balloc_try_alloc_block(ext4_inode_ref_t *, uint32_t, bool *);
  • uspace/lib/ext4/libext4_bitmap.c

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        libext4_bitmap.c
    35  * @brief       Ext4 bitmap operations.
     33 * @file  libext4_bitmap.c
     34 * @brief Ext4 bitmap operations.
    3635 */
    3736
     
    4544 * Index must be checked by caller, if it's not out of bounds.
    4645 *
    47  * @param bitmap        pointer to bitmap
    48  * @param index         index of bit in bitmap
     46 * @param bitmap Pointer to bitmap
     47 * @param index  Index of bit in bitmap
     48 *
    4949 */
    5050void ext4_bitmap_free_bit(uint8_t *bitmap, uint32_t index)
     
    5252        uint32_t byte_index = index / 8;
    5353        uint32_t bit_index = index % 8;
    54 
     54       
    5555        uint8_t *target = bitmap + byte_index;
    56 
     56       
    5757        *target &= ~ (1 << bit_index);
    5858}
     
    6262 * Index and count must be checked by caller, if they aren't out of bounds.
    6363 *
    64  * @param bitmap        pointer to bitmap
    65  * @param index         index of first bit to zeroed
    66  * @param count         number of bits to be zeroed
     64 * @param bitmap Pointer to bitmap
     65 * @param index  Index of first bit to zeroed
     66 * @param count  Number of bits to be zeroed
     67 *
    6768 */
    6869void ext4_bitmap_free_bits(uint8_t *bitmap, uint32_t index, uint32_t count)
     
    7273        uint32_t remaining = count;
    7374        uint32_t byte_index;
    74 
     75       
    7576        /* Align index to multiple of 8 */
    7677        while (((idx % 8) != 0) && (remaining > 0)) {
    77 
    7878                byte_index = idx / 8;
    7979                uint32_t bit_index = idx % 8;
    80 
     80               
    8181                target = bitmap + byte_index;
    82 
    8382                *target &= ~ (1 << bit_index);
    84 
     83               
    8584                idx++;
    8685                remaining--;
    8786        }
    88 
     87       
    8988        /* For < 8 bits this check necessary */
    90         if (remaining == 0) {
     89        if (remaining == 0)
    9190                return;
    92         }
    93 
     91       
    9492        assert((idx % 8) == 0);
    95 
     93       
    9694        byte_index = idx / 8;
    9795        target = bitmap + byte_index;
    98 
     96       
    9997        /* Zero the whole bytes */
    10098        while (remaining >= 8) {
    10199                *target = 0;
    102 
     100               
    103101                idx += 8;
    104102                remaining -= 8;
    105103                target++;
    106104        }
    107 
     105       
    108106        assert(remaining < 8);
    109 
     107       
    110108        /* Zero remaining bytes */
    111109        while (remaining != 0) {
    112 
    113110                byte_index = idx / 8;
    114111                uint32_t bit_index = idx % 8;
    115 
     112               
    116113                target = bitmap + byte_index;
    117 
    118114                *target &= ~ (1 << bit_index);
    119 
     115               
    120116                idx++;
    121117                remaining--;
     
    125121/** Set bit in bitmap to 1 (used).
    126122 *
    127  * @param bitmap        pointer to bitmap
    128  * @param index         index of bit to set
     123 * @param bitmap Pointer to bitmap
     124 * @param index  Index of bit to set
     125 *
    129126 */
    130127void ext4_bitmap_set_bit(uint8_t *bitmap, uint32_t index)
     
    132129        uint32_t byte_index = index / 8;
    133130        uint32_t bit_index = index % 8;
    134 
     131       
    135132        uint8_t *target = bitmap + byte_index;
    136 
     133       
    137134        *target |= 1 << bit_index;
    138135}
     
    140137/** Check if requested bit is free.
    141138 *
    142  * @param bitmap        pointer to bitmap
    143  * @param index         index of bit to be checked
    144  * @return                      true if bit is free, else false
     139 * @param bitmap Pointer to bitmap
     140 * @param index  Index of bit to be checked
     141 *
     142 * @return True if bit is free, else false
     143 *
    145144 */
    146145bool ext4_bitmap_is_free_bit(uint8_t *bitmap, uint32_t index)
     
    148147        uint32_t byte_index = index / 8;
    149148        uint32_t bit_index = index % 8;
    150 
     149       
    151150        uint8_t *target = bitmap + byte_index;
    152 
    153         if (*target & (1 << bit_index)) {
     151       
     152        if (*target & (1 << bit_index))
    154153                return false;
    155         } else {
     154        else
    156155                return true;
    157         }
    158 
    159 }
    160 
    161 /**     Try to find free byte and set the first bit as used.
    162  *
    163  * Walk through bitmap and try to find free byte ( == 0).
     156}
     157
     158/** Try to find free byte and set the first bit as used.
     159 *
     160 * Walk through bitmap and try to find free byte (equal to 0).
    164161 * If byte found, set the first bit as used.
    165162 *
    166  * @param bitmap        pointer to bitmap
    167  * @param start         index of bit, where the algorithm will begin
    168  * @param index         output value - index of bit (if found free byte)
    169  * @param max           maximum index of bit in bitmap
    170  * @return                      error code
    171  */
    172 int ext4_bitmap_find_free_byte_and_set_bit(uint8_t *bitmap, uint32_t start, uint32_t *index, uint32_t max)
     163 * @param bitmap Pointer to bitmap
     164 * @param start  Index of bit, where the algorithm will begin
     165 * @param index  Output value - index of bit (if found free byte)
     166 * @param max    Maximum index of bit in bitmap
     167 *
     168 * @return Error code
     169 *
     170 */
     171int ext4_bitmap_find_free_byte_and_set_bit(uint8_t *bitmap, uint32_t start,
     172    uint32_t *index, uint32_t max)
    173173{
    174174        uint32_t idx;
    175 
     175       
    176176        /* Align idx */
    177         if (start % 8) {
     177        if (start % 8)
    178178                idx = start + (8 - (start % 8));
    179         } else {
     179        else
    180180                idx = start;
    181         }
    182 
     181       
    183182        uint8_t *pos = bitmap + (idx / 8);
    184 
     183       
    185184        /* Try to find free byte */
    186185        while (idx < max) {
    187 
    188186                if (*pos == 0) {
    189187                        *pos |= 1;
    190 
     188                       
    191189                        *index = idx;
    192190                        return EOK;
    193191                }
    194 
     192               
    195193                idx += 8;
    196194                ++pos;
    197195        }
    198 
     196       
    199197        /* Free byte not found */
    200198        return ENOSPC;
     
    205203 * Walk through bitmap and try to find any free bit.
    206204 *
    207  * @param bitmap        pointer to bitmap
    208  * @param start_idx     index of bit, where algorithm will begin
    209  * @param index         output value - index of set bit (if found)
    210  * @param max           maximum index of bit in bitmap
    211  * @return                      error code
     205 * @param bitmap    Pointer to bitmap
     206 * @param start_idx Index of bit, where algorithm will begin
     207 * @param index     Output value - index of set bit (if found)
     208 * @param max       Maximum index of bit in bitmap
     209 *
     210 * @return Error code
     211 *
    212212 */
    213213int ext4_bitmap_find_free_bit_and_set(uint8_t *bitmap, uint32_t start_idx,
    214                 uint32_t *index, uint32_t max)
     214    uint32_t *index, uint32_t max)
    215215{
    216216        uint8_t *pos = bitmap + (start_idx / 8);
    217217        uint32_t idx = start_idx;
    218218        bool byte_part = false;
    219 
     219       
    220220        /* Check the rest of first byte */
    221221        while ((idx % 8) != 0) {
    222222                byte_part = true;
    223 
     223               
    224224                if ((*pos & (1 << (idx % 8))) == 0) {
    225225                        *pos |= (1 << (idx % 8));
     
    227227                        return EOK;
    228228                }
    229 
     229               
    230230                ++idx;
    231231        }
    232 
    233         if (byte_part) {
     232       
     233        if (byte_part)
    234234                ++pos;
    235         }
    236 
     235       
    237236        /* Check the whole bytes (255 = 11111111 binary) */
    238237        while (idx < max) {
    239 
    240238                if ((*pos & 255) != 255) {
    241                         /* free bit found */
     239                        /* Free bit found */
    242240                        break;
    243241                }
    244 
     242               
    245243                idx += 8;
    246244                ++pos;
    247245        }
    248 
     246       
    249247        /* If idx < max, some free bit found */
    250248        if (idx < max) {
    251 
    252249                /* Check which bit from byte is free */
    253250                for (uint8_t i = 0; i < 8; ++i) {
    254251                        if ((*pos & (1 << i)) == 0) {
    255                                 /* free bit found */
    256                                 *pos |=  (1 << i);
     252                                /* Free bit found */
     253                                *pos |= (1 << i);
     254                               
    257255                                *index = idx;
    258256                                return EOK;
    259257                        }
     258                       
    260259                        idx++;
    261260                }
    262261        }
    263 
     262       
    264263        /* Free bit not found */
    265264        return ENOSPC;
     
    268267/**
    269268 * @}
    270  */ 
     269 */
  • uspace/lib/ext4/libext4_bitmap.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_BITMAP_H_
     
    4141extern bool ext4_bitmap_is_free_bit(uint8_t *, uint32_t);
    4242extern int ext4_bitmap_find_free_byte_and_set_bit(uint8_t *, uint32_t,
    43                 uint32_t *, uint32_t);
    44 extern int ext4_bitmap_find_free_bit_and_set(uint8_t *, uint32_t,
    45                 uint32_t *, uint32_t);
     43    uint32_t *, uint32_t);
     44extern int ext4_bitmap_find_free_bit_and_set(uint8_t *, uint32_t, uint32_t *,
     45    uint32_t);
    4646
    4747#endif
  • uspace/lib/ext4/libext4_block_group.c

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        libext4_block_group.c
    35  * @brief       Ext4 block group structure operations.
     33 * @file  libext4_block_group.c
     34 * @brief Ext4 block group structure operations.
    3635 */
    3736
     
    4140/** Get address of block with data block bitmap.
    4241 *
    43  * @param bg    pointer to block group
    44  * @param sb    pointer to superblock
    45  * @return              address of block with block bitmap
     42 * @param bg Pointer to block group
     43 * @param sb Pointer to superblock
     44 *
     45 * @return Address of block with block bitmap
     46 *
    4647 */
    4748uint64_t ext4_block_group_get_block_bitmap(ext4_block_group_t *bg,
    48                 ext4_superblock_t *sb)
    49 {
    50         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
    51                 return ((uint64_t)uint32_t_le2host(bg->block_bitmap_hi) << 32) |
    52                         uint32_t_le2host(bg->block_bitmap_lo);
    53         } else {
     49    ext4_superblock_t *sb)
     50{
     51        if (ext4_superblock_get_desc_size(sb) >
     52            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
     53                return ((uint64_t) uint32_t_le2host(bg->block_bitmap_hi) << 32) |
     54                    uint32_t_le2host(bg->block_bitmap_lo);
     55        else
    5456                return uint32_t_le2host(bg->block_bitmap_lo);
    55         }
    5657}
    5758
    5859/** Set address of block with data block bitmap.
    5960 *
    60  * @param bg                    pointer to block group
    61  * @param sb                    pointer to superblock
    62  * @param block_bitmap  address of block with block bitmap
     61 * @param bg           Pointer to block group
     62 * @param sb           Pointer to superblock
     63 * @param block_bitmap Address of block with block bitmap
     64 *
    6365 */
    6466void ext4_block_group_set_block_bitmap(ext4_block_group_t *bg,
    65                 ext4_superblock_t *sb, uint64_t block_bitmap)
     67    ext4_superblock_t *sb, uint64_t block_bitmap)
    6668{
    6769        bg->block_bitmap_lo = host2uint32_t_le((block_bitmap << 32) >> 32);
    68 
    69         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
     70       
     71        if (ext4_superblock_get_desc_size(sb) >
     72            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
    7073                bg->block_bitmap_hi = host2uint32_t_le(block_bitmap >> 32);
    71         }
    7274}
    7375
    7476/** Get address of block with i-node bitmap.
    7577 *
    76  * @param bg    pointer to block group
    77  * @param sb    pointer to superblock
    78  * @return              address of block with i-node bitmap
     78 * @param bg Pointer to block group
     79 * @param sb Pointer to superblock
     80 *
     81 * @return Address of block with i-node bitmap
     82 *
    7983 */
    8084uint64_t ext4_block_group_get_inode_bitmap(ext4_block_group_t *bg,
    81                 ext4_superblock_t *sb)
    82 {
    83         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
    84                 return ((uint64_t)uint32_t_le2host(bg->inode_bitmap_hi) << 32) |
    85                         uint32_t_le2host(bg->inode_bitmap_lo);
    86         } else {
     85    ext4_superblock_t *sb)
     86{
     87        if (ext4_superblock_get_desc_size(sb) >
     88            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
     89                return ((uint64_t) uint32_t_le2host(bg->inode_bitmap_hi) << 32) |
     90                    uint32_t_le2host(bg->inode_bitmap_lo);
     91        else
    8792                return uint32_t_le2host(bg->inode_bitmap_lo);
    88         }
    89 
    9093}
    9194
    9295/** Set address of block with i-node bitmap.
    9396 *
    94  * @param bg                    pointer to block group
    95  * @param sb                    pointer to superblock
    96  * @param inode_bitmap  address of block with i-node bitmap
     97 * @param bg           Pointer to block group
     98 * @param sb           Pointer to superblock
     99 * @param inode_bitmap Address of block with i-node bitmap
     100 *
    97101 */
    98102void ext4_block_group_set_inode_bitmap(ext4_block_group_t *bg,
    99                 ext4_superblock_t *sb, uint64_t inode_bitmap)
     103    ext4_superblock_t *sb, uint64_t inode_bitmap)
    100104{
    101105        bg->inode_bitmap_lo = host2uint32_t_le((inode_bitmap << 32) >> 32);
    102 
    103         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
     106       
     107        if (ext4_superblock_get_desc_size(sb) >
     108            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
    104109                bg->inode_bitmap_hi = host2uint32_t_le(inode_bitmap >> 32);
    105         }
    106110}
    107111
    108112/** Get address of the first block of the i-node table.
    109113 *
    110  * @param bg    pointer to block group
    111  * @param sb    pointer to superblock
    112  * @return              address of first block of i-node table
     114 * @param bg Pointer to block group
     115 * @param sb Pointer to superblock
     116 *
     117 * @return Address of first block of i-node table
     118 *
    113119 */
    114120uint64_t ext4_block_group_get_inode_table_first_block(ext4_block_group_t *bg,
    115                 ext4_superblock_t *sb)
    116 {
    117         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
    118                 return ((uint64_t)uint32_t_le2host(bg->inode_table_first_block_hi) << 32) |
    119                         uint32_t_le2host(bg->inode_table_first_block_lo);
    120         } else {
     121    ext4_superblock_t *sb)
     122{
     123        if (ext4_superblock_get_desc_size(sb) >
     124            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
     125                return ((uint64_t)
     126                    uint32_t_le2host(bg->inode_table_first_block_hi) << 32) |
     127                    uint32_t_le2host(bg->inode_table_first_block_lo);
     128        else
    121129                return uint32_t_le2host(bg->inode_table_first_block_lo);
    122         }
    123130}
    124131
    125132/** Set address of the first block of the i-node table.
    126133 *
    127  * @param bg    pointer to block group
    128  * @param sb    pointer to superblock
    129  * @param inode_table_first address of first block of i-node table
     134 * @param bg                Pointer to block group
     135 * @param sb                Pointer to superblock
     136 * @param inode_table_first Address of first block of i-node table
     137 *
    130138 */
    131139void ext4_block_group_set_inode_table_first_block(ext4_block_group_t *bg,
    132                 ext4_superblock_t *sb, uint64_t inode_table_first)
     140    ext4_superblock_t *sb, uint64_t inode_table_first)
    133141{
    134142        bg->inode_table_first_block_lo =
    135                         host2uint32_t_le((inode_table_first << 32) >> 32);
    136 
    137         if (ext4_superblock_get_desc_size(sb) >
    138                         EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
    139 
     143            host2uint32_t_le((inode_table_first << 32) >> 32);
     144       
     145        if (ext4_superblock_get_desc_size(sb) >
     146            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
    140147                bg->inode_table_first_block_hi =
    141                                 host2uint32_t_le(inode_table_first >> 32);
    142         }
     148                    host2uint32_t_le(inode_table_first >> 32);
    143149}
    144150
    145151/** Get number of free blocks in block group.
    146152 *
    147  * @param bg    pointer to block group
    148  * @param sb    pointer to superblock
    149  * @return              number of free blocks in block group
     153 * @param bg Pointer to block group
     154 * @param sb Pointer to superblock
     155 *
     156 * @return Number of free blocks in block group
     157 *
    150158 */
    151159uint32_t ext4_block_group_get_free_blocks_count(ext4_block_group_t *bg,
    152                 ext4_superblock_t *sb)
    153 {
    154         if (ext4_superblock_get_desc_size(sb) >
    155                         EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
    156 
    157                 return ((uint32_t)uint16_t_le2host(bg->free_blocks_count_hi) << 16) |
    158                         uint16_t_le2host(bg->free_blocks_count_lo);
    159         } else {
     160    ext4_superblock_t *sb)
     161{
     162        if (ext4_superblock_get_desc_size(sb) >
     163            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
     164                return ((uint32_t)
     165                    uint16_t_le2host(bg->free_blocks_count_hi) << 16) |
     166                    uint16_t_le2host(bg->free_blocks_count_lo);
     167        else
    160168                return uint16_t_le2host(bg->free_blocks_count_lo);
    161         }
    162169}
    163170
    164171/** Set number of free blocks in block group.
    165172 *
    166  * @param bg    pointer to block group
    167  * @param sb    pointer to superblock
    168  * @param value number of free blocks in block group
     173 * @param bg    Pointer to block group
     174 * @param sb    Pointer to superblock
     175 * @param value Number of free blocks in block group
     176 *
    169177 */
    170178void ext4_block_group_set_free_blocks_count(ext4_block_group_t *bg,
    171                 ext4_superblock_t *sb, uint32_t value)
     179    ext4_superblock_t *sb, uint32_t value)
    172180{
    173181        bg->free_blocks_count_lo = host2uint16_t_le((value << 16) >> 16);
    174         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
     182        if (ext4_superblock_get_desc_size(sb) >
     183            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
    175184                bg->free_blocks_count_hi = host2uint16_t_le(value >> 16);
    176         }
    177185}
    178186
    179187/** Get number of free i-nodes in block group.
    180188 *
    181  * @param bg    pointer to block group
    182  * @param sb    pointer to superblock
    183  * @return              number of free i-nodes in block group
     189 * @param bg Pointer to block group
     190 * @param sb Pointer to superblock
     191 *
     192 * @return Number of free i-nodes in block group
     193 *
    184194 */
    185195uint32_t ext4_block_group_get_free_inodes_count(ext4_block_group_t *bg,
    186                 ext4_superblock_t *sb)
    187 {
    188         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
    189                 return ((uint32_t)uint16_t_le2host(bg->free_inodes_count_hi) << 16) |
    190                         uint16_t_le2host(bg->free_inodes_count_lo);
    191         } else {
     196    ext4_superblock_t *sb)
     197{
     198        if (ext4_superblock_get_desc_size(sb) >
     199            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
     200                return ((uint32_t)
     201                    uint16_t_le2host(bg->free_inodes_count_hi) << 16) |
     202                    uint16_t_le2host(bg->free_inodes_count_lo);
     203        else
    192204                return uint16_t_le2host(bg->free_inodes_count_lo);
    193         }
    194205}
    195206
    196207/** Set number of free i-nodes in block group.
    197208 *
    198  * @param bg    pointer to block group
    199  * @param sb    pointer to superblock
    200  * @param value number of free i-nodes in block group
     209 * @param bg    Pointer to block group
     210 * @param sb    Pointer to superblock
     211 * @param value Number of free i-nodes in block group
     212 *
    201213 */
    202214void ext4_block_group_set_free_inodes_count(ext4_block_group_t *bg,
    203                 ext4_superblock_t *sb, uint32_t value)
     215    ext4_superblock_t *sb, uint32_t value)
    204216{
    205217        bg->free_inodes_count_lo = host2uint16_t_le((value << 16) >> 16);
    206         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
     218        if (ext4_superblock_get_desc_size(sb) >
     219            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
    207220                bg->free_inodes_count_hi = host2uint16_t_le(value >> 16);
    208         }
    209221}
    210222
    211223/** Get number of used directories in block group.
    212224 *
    213  * @param bg    pointer to block group
    214  * @param sb    pointer to superblock
    215  * @return              number of used directories in block group
     225 * @param bg Pointer to block group
     226 * @param sb Pointer to superblock
     227 *
     228 * @return Number of used directories in block group
     229 *
    216230 */
    217231uint32_t ext4_block_group_get_used_dirs_count(ext4_block_group_t *bg,
    218                 ext4_superblock_t *sb)
    219 {
    220         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
    221                 return ((uint32_t)uint16_t_le2host(bg->used_dirs_count_hi) << 16) |
    222                         uint16_t_le2host(bg->used_dirs_count_lo);
    223         } else {
     232    ext4_superblock_t *sb)
     233{
     234        if (ext4_superblock_get_desc_size(sb) >
     235            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
     236                return ((uint32_t)
     237                    uint16_t_le2host(bg->used_dirs_count_hi) << 16) |
     238                    uint16_t_le2host(bg->used_dirs_count_lo);
     239        else
    224240                return uint16_t_le2host(bg->used_dirs_count_lo);
    225         }
    226241}
    227242
    228243/** Set number of used directories in block group.
    229244 *
    230  * @param bg    pointer to block group
    231  * @param sb    pointer to superblock
    232  * @param value number of used directories in block group
     245 * @param bg    Pointer to block group
     246 * @param sb    Pointer to superblock
     247 * @param value Number of used directories in block group
     248 *
    233249 */
    234250void ext4_block_group_set_used_dirs_count(ext4_block_group_t *bg,
    235                 ext4_superblock_t *sb, uint32_t count)
     251    ext4_superblock_t *sb, uint32_t count)
    236252{
    237253        bg->used_dirs_count_lo = host2uint16_t_le((count << 16) >> 16);
    238         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
     254        if (ext4_superblock_get_desc_size(sb) >
     255            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
    239256                bg->used_dirs_count_hi = host2uint16_t_le(count >> 16);
    240         }
    241257}
    242258
    243259/** Get flags of block group.
    244260 *
    245  * @param bg    pointer to block group
    246  * @return              flags of block group
     261 * @param bg Pointer to block group
     262 *
     263 * @return Flags of block group
     264 *
    247265 */
    248266uint16_t ext4_block_group_get_flags(ext4_block_group_t *bg)
     
    253271/** Set flags for block group.
    254272 *
    255  * @param bg    pointer to block group
    256  * @param flags flags for block group
     273 * @param bg    Pointer to block group
     274 * @param flags Flags for block group
     275 *
    257276 */
    258277void ext4_block_group_set_flags(ext4_block_group_t *bg, uint16_t flags)
     
    263282/** Get number of unused i-nodes.
    264283 *
    265  * @param bg    pointer to block group
    266  * @param sb    pointer to superblock
    267  * @return              number of unused i-nodes
     284 * @param bg Pointer to block group
     285 * @param sb Pointer to superblock
     286 *
     287 * @return Number of unused i-nodes
     288 *
    268289 */
    269290uint32_t ext4_block_group_get_itable_unused(ext4_block_group_t *bg,
    270                 ext4_superblock_t *sb)
    271 {
    272         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
    273                 return ((uint32_t)uint16_t_le2host(bg->itable_unused_hi) << 16) |
    274                         uint16_t_le2host(bg->itable_unused_lo);
    275         } else {
     291    ext4_superblock_t *sb)
     292{
     293        if (ext4_superblock_get_desc_size(sb) >
     294            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
     295                return ((uint32_t)
     296                    uint16_t_le2host(bg->itable_unused_hi) << 16) |
     297                    uint16_t_le2host(bg->itable_unused_lo);
     298        else
    276299                return uint16_t_le2host(bg->itable_unused_lo);
    277         }
    278300}
    279301
    280302/** Set number of unused i-nodes.
    281303 *
    282  * @param bg    pointer to block group
    283  * @param sb    pointer to superblock
    284  * @param value number of unused i-nodes
     304 * @param bg    Pointer to block group
     305 * @param sb    Pointer to superblock
     306 * @param value Number of unused i-nodes
     307 *
    285308 */
    286309void ext4_block_group_set_itable_unused(ext4_block_group_t *bg,
    287                 ext4_superblock_t *sb, uint32_t value)
     310    ext4_superblock_t *sb, uint32_t value)
    288311{
    289312        bg->itable_unused_lo = host2uint16_t_le((value << 16) >> 16);
    290         if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
     313        if (ext4_superblock_get_desc_size(sb) >
     314            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
    291315                bg->itable_unused_hi = host2uint16_t_le(value >> 16);
    292         }
    293 
    294316}
    295317
    296318/** Get checksum of block group.
    297319 *
    298  * @param bg    pointer to block group
    299  * @return              checksum of block group
     320 * @param bg Pointer to block group
     321 *
     322 * @return checksum of block group
     323 *
    300324 */
    301325uint16_t ext4_block_group_get_checksum(ext4_block_group_t *bg)
     
    306330/** Set checksum of block group.
    307331 *
    308  * @param bg            pointer to block group
    309  * @param checksum      cheksum of block group
     332 * @param bg       Pointer to block group
     333 * @param checksum Cheksum of block group
     334 *
    310335 */
    311336void ext4_block_group_set_checksum(ext4_block_group_t *bg, uint16_t checksum)
     
    316341/** Check if block group has a flag.
    317342 *
    318  * @param bg    pointer to block group
    319  * @param flag  flag to be checked
    320  * @return              true if flag is set to 1
     343 * @param bg   Pointer to block group
     344 * @param flag Flag to be checked
     345 *
     346 * @return True if flag is set to 1
     347 *
    321348 */
    322349bool ext4_block_group_has_flag(ext4_block_group_t *bg, uint32_t flag)
    323350{
    324         if (ext4_block_group_get_flags(bg) & flag) {
     351        if (ext4_block_group_get_flags(bg) & flag)
    325352                return true;
    326         }
     353       
    327354        return false;
    328355}
     
    330357/** Set (add) flag of block group.
    331358 *
    332  * @param bg    pointer to block group
    333  * @param flag  flag to be set
     359 * @param bg   Pointer to block group
     360 * @param flag Flag to be set
     361 *
    334362 */
    335363void ext4_block_group_set_flag(ext4_block_group_t *bg, uint32_t set_flag)
     
    342370/** Clear (remove) flag of block group.
    343371 *
    344  * @param bg    pointer to block group
    345  * @param flag  flag to be cleared
     372 * @param bg   Pointer to block group
     373 * @param flag Flag to be cleared
     374 *
    346375 */
    347376void ext4_block_group_clear_flag(ext4_block_group_t *bg, uint32_t clear_flag)
     
    352381}
    353382
    354 
    355383/**
    356384 * @}
    357  */ 
     385 */
  • uspace/lib/ext4/libext4_block_group.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_BLOCK_GROUP_H_
     
    3939
    4040extern uint64_t ext4_block_group_get_block_bitmap(ext4_block_group_t *,
    41                 ext4_superblock_t *);
     41    ext4_superblock_t *);
    4242extern void ext4_block_group_set_block_bitmap(ext4_block_group_t *,
    43                 ext4_superblock_t *, uint64_t);
     43    ext4_superblock_t *, uint64_t);
    4444extern uint64_t ext4_block_group_get_inode_bitmap(ext4_block_group_t *,
    45                 ext4_superblock_t *);
     45    ext4_superblock_t *);
    4646extern void ext4_block_group_set_inode_bitmap(ext4_block_group_t *,
    47                 ext4_superblock_t *, uint64_t);
     47    ext4_superblock_t *, uint64_t);
    4848extern uint64_t ext4_block_group_get_inode_table_first_block(
    49                 ext4_block_group_t *, ext4_superblock_t *);
    50 extern void ext4_block_group_set_inode_table_first_block(
    51                 ext4_block_group_t *, ext4_superblock_t *, uint64_t);
     49    ext4_block_group_t *, ext4_superblock_t *);
     50extern void ext4_block_group_set_inode_table_first_block(ext4_block_group_t *,
     51    ext4_superblock_t *, uint64_t);
    5252extern uint32_t ext4_block_group_get_free_blocks_count(ext4_block_group_t *,
    53                 ext4_superblock_t *);
     53    ext4_superblock_t *);
    5454extern void ext4_block_group_set_free_blocks_count(ext4_block_group_t *,
    55                 ext4_superblock_t *, uint32_t);
     55    ext4_superblock_t *, uint32_t);
    5656extern uint32_t ext4_block_group_get_free_inodes_count(ext4_block_group_t *,
    57                 ext4_superblock_t *);
     57    ext4_superblock_t *);
    5858extern void ext4_block_group_set_free_inodes_count(ext4_block_group_t *,
    59                 ext4_superblock_t *, uint32_t);
     59    ext4_superblock_t *, uint32_t);
    6060extern void ext4_block_group_set_free_inodes_count(ext4_block_group_t *,
    61                 ext4_superblock_t *, uint32_t);
     61    ext4_superblock_t *, uint32_t);
    6262extern uint32_t ext4_block_group_get_used_dirs_count(ext4_block_group_t *,
    63                 ext4_superblock_t *);
     63    ext4_superblock_t *);
    6464extern void ext4_block_group_set_used_dirs_count(ext4_block_group_t *,
    65                 ext4_superblock_t *, uint32_t);
     65    ext4_superblock_t *, uint32_t);
    6666extern uint16_t ext4_block_group_get_flags(ext4_block_group_t *);
    6767extern void ext4_block_group_set_flags(ext4_block_group_t *, uint16_t);
    6868extern uint32_t ext4_block_group_get_itable_unused(ext4_block_group_t *,
    69                 ext4_superblock_t *);
     69    ext4_superblock_t *);
    7070extern void ext4_block_group_set_itable_unused(ext4_block_group_t *,
    71                 ext4_superblock_t *, uint32_t);
     71    ext4_superblock_t *, uint32_t);
    7272extern uint16_t ext4_block_group_get_checksum(ext4_block_group_t *);
    7373extern void ext4_block_group_set_checksum(ext4_block_group_t *, uint16_t);
  • uspace/lib/ext4/libext4_crc.c

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333/**
    34  * @file        libext4_crc.c
    35  * @brief       CRC checksumming implementation from Linux.
     34 * @file  libext4_crc.c
     35 * @brief CRC checksumming implementation from Linux.
    3636 */
    3737
     
    4545 */
    4646uint16_t const crc16_table[256] = {
    47                 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
    48                 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
    49                 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
    50                 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
    51                 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
    52                 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
    53                 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
    54                 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
    55                 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
    56                 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
    57                 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
    58                 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
    59                 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
    60                 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
    61                 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
    62                 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
    63                 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
    64                 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
    65                 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
    66                 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
    67                 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
    68                 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
    69                 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
    70                 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
    71                 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
    72                 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
    73                 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
    74                 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
    75                 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
    76                 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
    77                 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
    78                 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
     47        0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
     48        0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
     49        0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
     50        0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
     51        0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
     52        0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
     53        0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
     54        0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
     55        0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
     56        0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
     57        0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
     58        0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
     59        0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
     60        0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
     61        0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
     62        0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
     63        0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
     64        0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
     65        0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
     66        0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
     67        0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
     68        0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
     69        0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
     70        0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
     71        0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
     72        0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
     73        0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
     74        0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
     75        0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
     76        0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
     77        0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
     78        0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
    7979};
    8080
    8181/** Modify CRC value.
    8282 *
    83  * @param crc   current CRC value
    84  * @param data  new byte of data to be "added" to CRC
    85  * @return              updated CRC value
     83 * @param crc   Current CRC value
     84 * @param data  New byte of data to be "added" to CRC
     85 *
     86 * @return Updated CRC value
     87 *
    8688 */
    8789static inline uint16_t crc16_byte(uint16_t crc, const uint8_t data)
     
    9294/** Compute the CRC-16 for the data buffer.
    9395 *
    94  * @param crc           previous CRC value
    95  * @param buffer        data pointer
    96  * @param len           number of bytes in the buffer
    97  * @return                      updated CRC value
     96 * @param crc    Previous CRC value
     97 * @param buffer Data pointer
     98 * @param len    Number of bytes in the buffer
     99 *
     100 * @return Updated CRC value
     101 *
    98102 */
    99103uint16_t crc16(uint16_t crc, const uint8_t *buffer, size_t len)
    100104{
    101                 while (len--) {
    102                         crc = crc16_byte(crc, *buffer++);
    103                 }
    104                 return crc;
     105        while (len--)
     106                crc = crc16_byte(crc, *buffer++);
     107       
     108        return crc;
    105109}
    106 
    107110
    108111/**
    109112 * @}
    110  */ 
     113 */
  • uspace/lib/ext4/libext4_crc.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_CRC_H_
     
    3535
    3636extern uint16_t crc16(uint16_t, const uint8_t *, size_t);
     37
    3738#endif
    3839
  • uspace/lib/ext4/libext4_directory.c

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        libext4_directory.c
    35  * @brief       Ext4 directory structure operations.
     33 * @file  libext4_directory.c
     34 * @brief Ext4 directory structure operations.
    3635 */
    3736
     
    3938#include <errno.h>
    4039#include <malloc.h>
    41 #include <string.h>
    4240#include "libext4.h"
    4341
    44 
    4542/** Get i-node number from directory entry.
    4643 *
    47  * @param de    directory entry
    48  * @return              i-node number
     44 * @param de Directory entry
     45 *
     46 * @return I-node number
     47 *
    4948 */
    5049uint32_t ext4_directory_entry_ll_get_inode(ext4_directory_entry_ll_t *de)
     
    5554/** Set i-node number to directory entry.
    5655 *
    57  * @param de    directory entry
    58  * @param inode i-node number
     56 * @param de    Directory entry
     57 * @param inode I-node number
     58 *
    5959 */
    6060void ext4_directory_entry_ll_set_inode(ext4_directory_entry_ll_t *de,
    61                 uint32_t inode)
     61    uint32_t inode)
    6262{
    6363        de->inode = host2uint32_t_le(inode);
     
    6666/** Get directory entry length.
    6767 *
    68  * @param de    directory entry
    69  * @return              entry length
    70  */
    71 uint16_t ext4_directory_entry_ll_get_entry_length(
    72                 ext4_directory_entry_ll_t *de)
     68 * @param de Directory entry
     69 *
     70 * @return Entry length
     71 *
     72 */
     73uint16_t ext4_directory_entry_ll_get_entry_length(ext4_directory_entry_ll_t *de)
    7374{
    7475        return uint16_t_le2host(de->entry_length);
     
    7778/** Set directory entry length.
    7879 *
    79  * @param de            directory entry
    80  * @param length        entry length
    81  */
    82 
     80 * @param de     Directory entry
     81 * @param length Entry length
     82 *
     83 */
    8384void ext4_directory_entry_ll_set_entry_length(ext4_directory_entry_ll_t *de,
    84                 uint16_t length)
     85    uint16_t length)
    8586{
    8687        de->entry_length = host2uint16_t_le(length);
     
    8990/** Get directory entry name length.
    9091 *
    91  * @param sb    superblock
    92  * @param de    directory entry
    93  * @return              entry name length
    94  */
    95 uint16_t ext4_directory_entry_ll_get_name_length(
    96     ext4_superblock_t *sb, ext4_directory_entry_ll_t *de)
    97 {
    98         if (ext4_superblock_get_rev_level(sb) == 0 &&
    99             ext4_superblock_get_minor_rev_level(sb) < 5) {
    100 
     92 * @param sb Superblock
     93 * @param de Directory entry
     94 *
     95 * @return Entry name length
     96 *
     97 */
     98uint16_t ext4_directory_entry_ll_get_name_length(ext4_superblock_t *sb,
     99    ext4_directory_entry_ll_t *de)
     100{
     101        if ((ext4_superblock_get_rev_level(sb) == 0) &&
     102            (ext4_superblock_get_minor_rev_level(sb) < 5))
    101103                return ((uint16_t)de->name_length_high) << 8 |
    102                             ((uint16_t)de->name_length);
    103 
    104         }
     104                    ((uint16_t)de->name_length);
     105       
    105106        return de->name_length;
    106107
     
    109110/** Set directory entry name length.
    110111 *
    111  * @param sb            superblock
    112  * @param de            directory entry
    113  * @param length        entry name length
     112 * @param sb     Superblock
     113 * @param de     Directory entry
     114 * @param length Entry name length
     115 *
    114116 */
    115117void ext4_directory_entry_ll_set_name_length(ext4_superblock_t *sb,
    116                 ext4_directory_entry_ll_t *de, uint16_t length)
     118    ext4_directory_entry_ll_t *de, uint16_t length)
    117119{
    118120        de->name_length = (length << 8) >> 8;
    119 
    120         if (ext4_superblock_get_rev_level(sb) == 0 &&
    121                     ext4_superblock_get_minor_rev_level(sb) < 5) {
    122 
     121       
     122        if ((ext4_superblock_get_rev_level(sb) == 0) &&
     123            (ext4_superblock_get_minor_rev_level(sb) < 5))
    123124                de->name_length_high = length >> 8;
    124         }
     125       
     126        /* Else do nothing */
    125127}
    126128
    127129/** Get i-node type of directory entry.
    128130 *
    129  * @param sb    superblock
    130  * @param de    directory entry
    131  * @return              i-node type (file, dir, etc.)
    132  */
    133 uint8_t ext4_directory_entry_ll_get_inode_type(
    134                 ext4_superblock_t *sb, ext4_directory_entry_ll_t *de)
    135 {
    136         if (ext4_superblock_get_rev_level(sb) > 0 ||
    137                     ext4_superblock_get_minor_rev_level(sb) >= 5) {
    138 
    139                         return de->inode_type;
    140         }
    141 
     131 * @param sb Superblock
     132 * @param de Directory entry
     133 *
     134 * @return I-node type (file, dir, etc.)
     135 *
     136 */
     137uint8_t ext4_directory_entry_ll_get_inode_type(ext4_superblock_t *sb,
     138    ext4_directory_entry_ll_t *de)
     139{
     140        if ((ext4_superblock_get_rev_level(sb) > 0) ||
     141            (ext4_superblock_get_minor_rev_level(sb) >= 5))
     142                return de->inode_type;
     143       
    142144        return EXT4_DIRECTORY_FILETYPE_UNKNOWN;
    143 
    144145}
    145146
    146147/** Set i-node type of directory entry.
    147148 *
    148  * @param sb    superblock
    149  * @param de    directory entry
    150  * @param type  i-node type (file, dir, etc.)
    151  */
    152 void ext4_directory_entry_ll_set_inode_type(
    153                 ext4_superblock_t *sb, ext4_directory_entry_ll_t *de, uint8_t type)
    154 {
    155         if (ext4_superblock_get_rev_level(sb) > 0 ||
    156                         ext4_superblock_get_minor_rev_level(sb) >= 5) {
    157 
     149 * @param sb   Superblock
     150 * @param de   Directory entry
     151 * @param type I-node type (file, dir, etc.)
     152 *
     153 */
     154void ext4_directory_entry_ll_set_inode_type(ext4_superblock_t *sb,
     155    ext4_directory_entry_ll_t *de, uint8_t type)
     156{
     157        if ((ext4_superblock_get_rev_level(sb) > 0) ||
     158            (ext4_superblock_get_minor_rev_level(sb) >= 5))
    158159                de->inode_type = type;
    159         }
    160 
    161         /* else do nothing */
    162 
    163 }
    164 
    165 static int ext4_directory_iterator_seek(
    166                 ext4_directory_iterator_t *, aoff64_t);
    167 static int ext4_directory_iterator_set(
    168                 ext4_directory_iterator_t *, uint32_t);
    169 
     160       
     161        /* Else do nothing */
     162}
     163
     164static int ext4_directory_iterator_seek(ext4_directory_iterator_t *, aoff64_t);
     165static int ext4_directory_iterator_set(ext4_directory_iterator_t *, uint32_t);
    170166
    171167/** Initialize directory iterator.
     
    173169 * Set position to the first valid entry from the required position.
    174170 *
    175  * @param it                    pointer to iterator to be initialized
    176  * @param inode_ref             directory i-node
    177  * @param pos                   position to start reading entries from
    178  * @return                              error code
     171 * @param it        Pointer to iterator to be initialized
     172 * @param inode_ref Directory i-node
     173 * @param pos       Position to start reading entries from
     174 *
     175 * @return Error code
     176 *
    179177 */
    180178int ext4_directory_iterator_init(ext4_directory_iterator_t *it,
    181                 ext4_inode_ref_t *inode_ref, aoff64_t pos)
     179    ext4_inode_ref_t *inode_ref, aoff64_t pos)
    182180{
    183181        it->inode_ref = inode_ref;
     
    185183        it->current_offset = 0;
    186184        it->current_block = NULL;
    187 
     185       
    188186        return ext4_directory_iterator_seek(it, pos);
    189187}
     
    191189/** Jump to the next valid entry
    192190 *
    193  * @param it    initialized iterator
    194  * @return              error code
     191 * @param it Initialized iterator
     192 *
     193 * @return Error code
     194 *
    195195 */
    196196int ext4_directory_iterator_next(ext4_directory_iterator_t *it)
    197197{
    198         uint16_t skip;
    199 
    200198        assert(it->current != NULL);
    201 
    202         skip = ext4_directory_entry_ll_get_entry_length(it->current);
    203 
     199       
     200        uint16_t skip = ext4_directory_entry_ll_get_entry_length(it->current);
     201       
    204202        return ext4_directory_iterator_seek(it, it->current_offset + skip);
    205203}
     
    209207 * Here can be jumped to the next data block.
    210208 *
    211  * @param it    initialized iterator
    212  * @param pos   position of the next entry
    213  * @return              error code
     209 * @param it  Initialized iterator
     210 * @param pos Position of the next entry
     211 *
     212 * @return Error code
     213 *
    214214 */
    215215int ext4_directory_iterator_seek(ext4_directory_iterator_t *it, aoff64_t pos)
    216216{
    217         int rc;
    218 
    219         uint64_t size = ext4_inode_get_size(
    220                         it->inode_ref->fs->superblock, it->inode_ref->inode);
    221 
     217        uint64_t size = ext4_inode_get_size(it->inode_ref->fs->superblock,
     218            it->inode_ref->inode);
     219       
    222220        /* The iterator is not valid until we seek to the desired position */
    223221        it->current = NULL;
    224 
     222       
    225223        /* Are we at the end? */
    226224        if (pos >= size) {
    227225                if (it->current_block) {
    228                         rc = block_put(it->current_block);
     226                        int rc = block_put(it->current_block);
    229227                        it->current_block = NULL;
    230                         if (rc != EOK) {
     228                       
     229                        if (rc != EOK)
    231230                                return rc;
    232                         }
    233                 }
    234 
     231                }
     232               
    235233                it->current_offset = pos;
    236234                return EOK;
    237235        }
    238 
     236       
    239237        /* Compute next block address */
    240         uint32_t block_size = ext4_superblock_get_block_size(
    241                         it->inode_ref->fs->superblock);
     238        uint32_t block_size =
     239            ext4_superblock_get_block_size(it->inode_ref->fs->superblock);
    242240        aoff64_t current_block_idx = it->current_offset / block_size;
    243241        aoff64_t next_block_idx = pos / block_size;
    244 
    245         /* If we don't have a block or are moving accross block boundary,
     242       
     243        /*
     244         * If we don't have a block or are moving accross block boundary,
    246245         * we need to get another block
    247246         */
    248         if (it->current_block == NULL || current_block_idx != next_block_idx) {
     247        if ((it->current_block == NULL) ||
     248            (current_block_idx != next_block_idx)) {
    249249                if (it->current_block) {
    250                         rc = block_put(it->current_block);
     250                        int rc = block_put(it->current_block);
    251251                        it->current_block = NULL;
    252                         if (rc != EOK) {
     252                       
     253                        if (rc != EOK)
    253254                                return rc;
    254                         }
    255                 }
    256 
     255                }
     256               
    257257                uint32_t next_block_phys_idx;
    258                 rc = ext4_filesystem_get_inode_data_block_index(it->inode_ref,
    259                                 next_block_idx, &next_block_phys_idx);
    260                 if (rc != EOK) {
     258                int rc = ext4_filesystem_get_inode_data_block_index(it->inode_ref,
     259                    next_block_idx, &next_block_phys_idx);
     260                if (rc != EOK)
    261261                        return rc;
    262                 }
    263 
     262               
    264263                rc = block_get(&it->current_block, it->inode_ref->fs->device,
    265                                 next_block_phys_idx, BLOCK_FLAGS_NONE);
     264                    next_block_phys_idx, BLOCK_FLAGS_NONE);
    266265                if (rc != EOK) {
    267266                        it->current_block = NULL;
     
    269268                }
    270269        }
    271 
     270       
    272271        it->current_offset = pos;
    273 
     272       
    274273        return ext4_directory_iterator_set(it, block_size);
    275274}
     
    277276/** Do some checks before returning iterator.
    278277 *
    279  * @param it                    iterator to be checked
    280  * @param block_size    size of data block
    281  * @return                              error code
     278 * @param it         Iterator to be checked
     279 * @param block_size Size of data block
     280 *
     281 * @return Error code
     282 *
    282283 */
    283284static int ext4_directory_iterator_set(ext4_directory_iterator_t *it,
    284285    uint32_t block_size)
    285286{
    286 
    287287        it->current = NULL;
    288 
     288       
    289289        uint32_t offset_in_block = it->current_offset % block_size;
    290 
     290       
    291291        /* Ensure proper alignment */
    292         if ((offset_in_block % 4) != 0) {
     292        if ((offset_in_block % 4) != 0)
    293293                return EIO;
    294         }
    295 
     294       
    296295        /* Ensure that the core of the entry does not overflow the block */
    297         if (offset_in_block > block_size - 8) {
     296        if (offset_in_block > block_size - 8)
    298297                return EIO;
    299         }
    300 
    301         ext4_directory_entry_ll_t *entry = it->current_block->data + offset_in_block;
    302 
     298       
     299        ext4_directory_entry_ll_t *entry =
     300            it->current_block->data + offset_in_block;
     301       
    303302        /* Ensure that the whole entry does not overflow the block */
    304303        uint16_t length = ext4_directory_entry_ll_get_entry_length(entry);
    305         if (offset_in_block + length > block_size) {
     304        if (offset_in_block + length > block_size)
    306305                return EIO;
    307         }
    308 
     306       
    309307        /* Ensure the name length is not too large */
    310         if (ext4_directory_entry_ll_get_name_length(it->inode_ref->fs->superblock,
    311             entry) > length-8) {
     308        if (ext4_directory_entry_ll_get_name_length(
     309            it->inode_ref->fs->superblock, entry) > length-8)
    312310                return EIO;
    313         }
    314 
     311       
    315312        /* Everything OK - "publish" the entry */
    316313        it->current = entry;
     
    318315}
    319316
    320 
    321317/** Uninitialize directory iterator.
    322318 *
    323319 * Release all allocated structures.
    324320 *
    325  * @param it    iterator to be finished
    326  * @return              error code
     321 * @param it Iterator to be finished
     322 *
     323 * @return Error code
     324 *
    327325 */
    328326int ext4_directory_iterator_fini(ext4_directory_iterator_t *it)
    329327{
    330         int rc;
    331 
    332328        it->inode_ref = NULL;
    333329        it->current = NULL;
    334 
    335         if (it->current_block) {
    336                 rc = block_put(it->current_block);
    337                 if (rc != EOK) {
    338                         return rc;
    339                 }
    340         }
    341 
     330       
     331        if (it->current_block)
     332                return block_put(it->current_block);
     333       
    342334        return EOK;
    343335}
    344336
    345 /**     Write directory entry to concrete data block.
    346  *
    347  * @param sb            superblock
    348  * @param entry         pointer to entry to be written
    349  * @param entry_len     lenght of new entry
    350  * @param child         child i-node to be written to new entry
    351  * @param name          name of the new entry
    352  * @param name_len      length of entry name
     337/** Write directory entry to concrete data block.
     338 *
     339 * @param sb        Superblock
     340 * @param entry     Pointer to entry to be written
     341 * @param entry_len Length of new entry
     342 * @param child     Child i-node to be written to new entry
     343 * @param name      Name of the new entry
     344 * @param name_len  Length of entry name
     345 *
    353346 */
    354347void ext4_directory_write_entry(ext4_superblock_t *sb,
    355                 ext4_directory_entry_ll_t *entry, uint16_t entry_len,
    356                 ext4_inode_ref_t *child, const char *name, size_t name_len)
    357 {
    358 
     348    ext4_directory_entry_ll_t *entry, uint16_t entry_len,
     349    ext4_inode_ref_t *child, const char *name, size_t name_len)
     350{
    359351        /* Check maximum entry length */
    360352        uint32_t block_size = ext4_superblock_get_block_size(sb);
    361353        assert(entry_len <= block_size);
    362 
     354       
    363355        /* Set basic attributes */
    364356        ext4_directory_entry_ll_set_inode(entry, child->index);
    365357        ext4_directory_entry_ll_set_entry_length(entry, entry_len);
    366358        ext4_directory_entry_ll_set_name_length(sb, entry, name_len);
    367 
     359       
    368360        /* Write name */
    369361        memcpy(entry->name, name, name_len);
    370 
     362       
    371363        /* Set type of entry */
    372         if (ext4_inode_is_type(sb, child->inode, EXT4_INODE_MODE_DIRECTORY)) {
    373                 ext4_directory_entry_ll_set_inode_type(
    374                                 sb, entry, EXT4_DIRECTORY_FILETYPE_DIR);
    375         } else {
    376                 ext4_directory_entry_ll_set_inode_type(
    377                                 sb, entry, EXT4_DIRECTORY_FILETYPE_REG_FILE);
    378         }
    379 
     364        if (ext4_inode_is_type(sb, child->inode, EXT4_INODE_MODE_DIRECTORY))
     365                ext4_directory_entry_ll_set_inode_type(sb, entry,
     366                    EXT4_DIRECTORY_FILETYPE_DIR);
     367        else
     368                ext4_directory_entry_ll_set_inode_type(sb, entry,
     369                    EXT4_DIRECTORY_FILETYPE_REG_FILE);
    380370}
    381371
    382372/** Add new entry to the directory.
    383373 *
    384  * @param parent        directory i-node
    385  * @param name          name of new entry
    386  * @param child         i-node to be referenced from new entry
    387  * @return                      error code
    388  */
    389 int ext4_directory_add_entry(ext4_inode_ref_t * parent,
    390                 const char *name, ext4_inode_ref_t *child)
    391 {
    392         int rc;
    393 
     374 * @param parent Directory i-node
     375 * @param name   Name of new entry
     376 * @param child  I-node to be referenced from new entry
     377 *
     378 * @return Error code
     379 *
     380 */
     381int ext4_directory_add_entry(ext4_inode_ref_t *parent, const char *name,
     382    ext4_inode_ref_t *child)
     383{
    394384        ext4_filesystem_t *fs = parent->fs;
    395 
     385       
    396386        /* Index adding (if allowed) */
    397         if (ext4_superblock_has_feature_compatible(fs->superblock, EXT4_FEATURE_COMPAT_DIR_INDEX) &&
    398                         ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX)) {
    399 
    400                 rc = ext4_directory_dx_add_entry(parent, child, name);
    401 
     387        if ((ext4_superblock_has_feature_compatible(fs->superblock,
     388            EXT4_FEATURE_COMPAT_DIR_INDEX)) &&
     389            (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {
     390                int rc = ext4_directory_dx_add_entry(parent, child, name);
     391               
    402392                /* Check if index is not corrupted */
    403393                if (rc != EXT4_ERR_BAD_DX_DIR) {
    404 
    405                         if (rc != EOK) {
     394                        if (rc != EOK)
    406395                                return rc;
    407                         }
    408 
     396                       
    409397                        return EOK;
    410398                }
    411 
     399               
    412400                /* Needed to clear dir index flag if corrupted */
    413401                ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
    414402                parent->dirty = true;
    415403        }
    416 
     404       
    417405        /* Linear algorithm */
    418 
    419         uint32_t iblock = 0, fblock = 0;
     406       
     407        uint32_t iblock = 0;
     408        uint32_t fblock = 0;
    420409        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    421410        uint32_t inode_size = ext4_inode_get_size(fs->superblock, parent->inode);
    422411        uint32_t total_blocks = inode_size / block_size;
    423 
    424         uint32_t name_len = strlen(name);
    425 
     412       
     413        uint32_t name_len = str_size(name);
     414       
    426415        /* Find block, where is space for new entry and try to add */
    427416        bool success = false;
    428417        for (iblock = 0; iblock < total_blocks; ++iblock) {
    429 
    430                 rc = ext4_filesystem_get_inode_data_block_index(parent, iblock, &fblock);
    431                 if (rc != EOK) {
     418                int rc = ext4_filesystem_get_inode_data_block_index(parent,
     419                    iblock, &fblock);
     420                if (rc != EOK)
    432421                        return rc;
    433                 }
    434 
     422               
    435423                block_t *block;
    436424                rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
    437                 if (rc != EOK) {
     425                if (rc != EOK)
    438426                        return rc;
    439                 }
    440 
     427               
    441428                /* If adding is successful, function can finish */
    442                 rc = ext4_directory_try_insert_entry(fs->superblock, block, child, name, name_len);
    443                 if (rc == EOK) {
     429                rc = ext4_directory_try_insert_entry(fs->superblock, block,
     430                    child, name, name_len);
     431                if (rc == EOK)
    444432                        success = true;
    445                 }
    446 
     433               
    447434                rc = block_put(block);
    448                 if (rc != EOK) {
     435                if (rc != EOK)
    449436                        return rc;
    450                 }
    451 
    452                 if (success) {
     437               
     438                if (success)
    453439                        return EOK;
    454                 }
    455         }
    456 
     440        }
     441       
    457442        /* No free block found - needed to allocate next data block */
    458 
     443       
    459444        iblock = 0;
    460445        fblock = 0;
    461         rc = ext4_filesystem_append_inode_block(parent, &fblock, &iblock);
    462         if (rc != EOK) {
     446        int rc = ext4_filesystem_append_inode_block(parent, &fblock, &iblock);
     447        if (rc != EOK)
    463448                return rc;
    464         }
    465 
     449       
    466450        /* Load new block */
    467451        block_t *new_block;
    468452        rc = block_get(&new_block, fs->device, fblock, BLOCK_FLAGS_NOREAD);
    469         if (rc != EOK) {
     453        if (rc != EOK)
    470454                return rc;
    471         }
    472 
     455       
    473456        /* Fill block with zeroes */
    474457        memset(new_block->data, 0, block_size);
    475458        ext4_directory_entry_ll_t *block_entry = new_block->data;
    476         ext4_directory_write_entry(fs->superblock, block_entry, block_size, child, name, name_len);
    477 
     459        ext4_directory_write_entry(fs->superblock, block_entry, block_size,
     460            child, name, name_len);
     461       
    478462        /* Save new block */
    479463        new_block->dirty = true;
    480464        rc = block_put(new_block);
    481         if (rc != EOK) {
    482                 return rc;
    483         }
    484 
    485         return EOK;
     465       
     466        return rc;
    486467}
    487468
    488469/** Find directory entry with passed name.
    489470 *
    490  * @param result        result structure to be returned if entry found
    491  * @param parent        directory i-node
    492  * @param name          name of entry to be found
    493  * @return                      error code
     471 * @param result Result structure to be returned if entry found
     472 * @param parent Directory i-node
     473 * @param name   Name of entry to be found
     474 *
     475 * @return Error code
     476 *
    494477 */
    495478int ext4_directory_find_entry(ext4_directory_search_result_t *result,
    496                 ext4_inode_ref_t *parent, const char *name)
    497 {
    498         int rc;
    499         uint32_t name_len = strlen(name);
    500 
     479    ext4_inode_ref_t *parent, const char *name)
     480{
     481        uint32_t name_len = str_size(name);
     482       
    501483        ext4_superblock_t *sb = parent->fs->superblock;
    502 
     484       
    503485        /* Index search */
    504         if (ext4_superblock_has_feature_compatible(sb, EXT4_FEATURE_COMPAT_DIR_INDEX) &&
    505                         ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX)) {
    506 
    507                 rc = ext4_directory_dx_find_entry(result, parent, name_len, name);
    508 
     486        if ((ext4_superblock_has_feature_compatible(sb,
     487            EXT4_FEATURE_COMPAT_DIR_INDEX)) &&
     488            (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {
     489                int rc = ext4_directory_dx_find_entry(result, parent, name_len,
     490                    name);
     491               
    509492                /* Check if index is not corrupted */
    510493                if (rc != EXT4_ERR_BAD_DX_DIR) {
    511 
    512                         if (rc != EOK) {
     494                        if (rc != EOK)
    513495                                return rc;
    514                         }
     496                       
    515497                        return EOK;
    516498                }
    517 
     499               
    518500                /* Needed to clear dir index flag if corrupted */
    519501                ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
    520502                parent->dirty = true;
    521 
    522         }
    523 
     503        }
     504       
    524505        /* Linear algorithm */
    525 
    526         uint32_t iblock, fblock;
     506       
     507        uint32_t iblock;
     508        uint32_t fblock;
    527509        uint32_t block_size = ext4_superblock_get_block_size(sb);
    528510        uint32_t inode_size = ext4_inode_get_size(sb, parent->inode);
    529511        uint32_t total_blocks = inode_size / block_size;
    530 
     512       
    531513        /* Walk through all data blocks */
    532514        for (iblock = 0; iblock < total_blocks; ++iblock) {
    533 
    534515                /* Load block address */
    535                 rc = ext4_filesystem_get_inode_data_block_index(parent, iblock, &fblock);
    536                 if (rc != EOK) {
     516                int rc = ext4_filesystem_get_inode_data_block_index(parent, iblock,
     517                    &fblock);
     518                if (rc != EOK)
    537519                        return rc;
    538                 }
    539 
     520               
    540521                /* Load data block */
    541522                block_t *block;
    542523                rc = block_get(&block, parent->fs->device, fblock, BLOCK_FLAGS_NONE);
    543                 if (rc != EOK) {
     524                if (rc != EOK)
    544525                        return rc;
    545                 }
    546 
     526               
    547527                /* Try to find entry in block */
    548528                ext4_directory_entry_ll_t *res_entry;
    549                 rc = ext4_directory_find_in_block(block, sb, name_len, name, &res_entry);
     529                rc = ext4_directory_find_in_block(block, sb, name_len, name,
     530                    &res_entry);
    550531                if (rc == EOK) {
    551532                        result->block = block;
     
    553534                        return EOK;
    554535                }
    555 
     536               
    556537                /* Entry not found - put block and continue to the next block */
    557 
     538               
    558539                rc = block_put(block);
    559                 if (rc != EOK) {
     540                if (rc != EOK)
    560541                        return rc;
    561                 }
    562         }
    563 
     542        }
     543       
    564544        /* Entry was not found */
    565 
     545       
    566546        result->block = NULL;
    567547        result->dentry =  NULL;
    568 
     548       
    569549        return ENOENT;
    570550}
    571551
    572 
    573552/** Remove directory entry.
    574553 *
    575  * @param parent        directory i-node
    576  * @param name          name of the entry to be removed
    577  * @return                      error code
     554 * @param parent Directory i-node
     555 * @param name   Name of the entry to be removed
     556 *
     557 * @return Error code
     558 *
    578559 */
    579560int ext4_directory_remove_entry(ext4_inode_ref_t *parent, const char *name)
    580561{
    581         int rc;
    582 
    583562        /* Check if removing from directory */
    584563        if (!ext4_inode_is_type(parent->fs->superblock, parent->inode,
    585             EXT4_INODE_MODE_DIRECTORY)) {
     564            EXT4_INODE_MODE_DIRECTORY))
    586565                return ENOTDIR;
    587         }
    588 
     566       
    589567        /* Try to find entry */
    590568        ext4_directory_search_result_t result;
    591         rc = ext4_directory_find_entry(&result, parent, name);
    592         if (rc != EOK) {
     569        int rc = ext4_directory_find_entry(&result, parent, name);
     570        if (rc != EOK)
    593571                return rc;
    594         }
    595 
     572       
    596573        /* Invalidate entry */
    597574        ext4_directory_entry_ll_set_inode(result.dentry, 0);
    598 
     575       
    599576        /* Store entry position in block */
    600         uint32_t pos = (void *)result.dentry - result.block->data;
    601 
    602         /* If entry is not the first in block, it must be merged
     577        uint32_t pos = (void *) result.dentry - result.block->data;
     578       
     579        /*
     580         * If entry is not the first in block, it must be merged
    603581         * with previous entry
    604582         */
    605583        if (pos != 0) {
    606 
    607584                uint32_t offset = 0;
    608 
     585               
    609586                /* Start from the first entry in block */
    610587                ext4_directory_entry_ll_t *tmp_dentry = result.block->data;
    611588                uint16_t tmp_dentry_length =
    612                                 ext4_directory_entry_ll_get_entry_length(tmp_dentry);
    613 
     589                    ext4_directory_entry_ll_get_entry_length(tmp_dentry);
     590               
    614591                /* Find direct predecessor of removed entry */
    615592                while ((offset + tmp_dentry_length) < pos) {
    616                         offset += ext4_directory_entry_ll_get_entry_length(tmp_dentry);
     593                        offset +=
     594                            ext4_directory_entry_ll_get_entry_length(tmp_dentry);
    617595                        tmp_dentry = result.block->data + offset;
    618596                        tmp_dentry_length =
    619                                         ext4_directory_entry_ll_get_entry_length(tmp_dentry);
    620                 }
    621 
     597                            ext4_directory_entry_ll_get_entry_length(tmp_dentry);
     598                }
     599               
    622600                assert(tmp_dentry_length + offset == pos);
    623 
     601               
    624602                /* Add to removed entry length to predecessor's length */
    625603                uint16_t del_entry_length =
    626                                 ext4_directory_entry_ll_get_entry_length(result.dentry);
     604                    ext4_directory_entry_ll_get_entry_length(result.dentry);
    627605                ext4_directory_entry_ll_set_entry_length(tmp_dentry,
    628                                 tmp_dentry_length + del_entry_length);
    629 
    630         }
    631 
     606                    tmp_dentry_length + del_entry_length);
     607        }
     608       
    632609        result.block->dirty = true;
    633 
     610       
    634611        return ext4_directory_destroy_result(&result);
    635612}
     
    637614/** Try to insert entry to concrete data block.
    638615 *
    639  * @param sb                    superblock
    640  * @param target_block  block to try to insert entry to
    641  * @param child                 child i-node to be inserted by new entry
    642  * @param name                  name of the new entry
    643  * @param name_len              length of the new entry name
    644  * @return                              error code
     616 * @param sb           Superblock
     617 * @param target_block Block to try to insert entry to
     618 * @param child        Child i-node to be inserted by new entry
     619 * @param name         Name of the new entry
     620 * @param name_len     Length of the new entry name
     621 *
     622 * @return Error code
     623 *
    645624 */
    646625int ext4_directory_try_insert_entry(ext4_superblock_t *sb,
    647                 block_t *target_block, ext4_inode_ref_t *child,
    648                 const char *name, uint32_t name_len)
     626    block_t *target_block, ext4_inode_ref_t *child, const char *name,
     627    uint32_t name_len)
    649628{
    650629        /* Compute required length entry and align it to 4 bytes */
    651         uint32_t block_size = ext4_superblock_get_block_size(sb);
    652         uint16_t required_len = sizeof(ext4_fake_directory_entry_t) + name_len;
    653         if ((required_len % 4) != 0) {
    654                 required_len += 4 - (required_len % 4);
    655         }
    656 
    657         /* Initialize pointers, stop means to upper bound */
    658         ext4_directory_entry_ll_t *dentry = target_block->data;
    659         ext4_directory_entry_ll_t *stop = target_block->data + block_size;
    660 
    661         /* Walk through the block and check for invalid entries
    662          * or entries with free space for new entry
    663          */
    664         while (dentry < stop) {
    665 
    666                 uint32_t inode = ext4_directory_entry_ll_get_inode(dentry);
    667                 uint16_t rec_len = ext4_directory_entry_ll_get_entry_length(dentry);
    668 
    669                 /* If invalid and large enough entry, use it */
    670                 if ((inode == 0) && (rec_len >= required_len)) {
    671                         ext4_directory_write_entry(sb, dentry, rec_len, child, name, name_len);
    672                         target_block->dirty = true;
    673                         return EOK;
    674                 }
    675 
    676                 /* Valid entry, try to split it */
    677                 if (inode != 0) {
    678                         uint16_t used_name_len =
    679                                         ext4_directory_entry_ll_get_name_length(sb, dentry);
    680 
    681                         uint16_t used_space =
    682                                         sizeof(ext4_fake_directory_entry_t) + used_name_len;
    683                         if ((used_name_len % 4) != 0) {
    684                                 used_space += 4 - (used_name_len % 4);
    685                         }
    686                         uint16_t free_space = rec_len - used_space;
    687 
    688                         /* There is free space for new entry */
    689                         if (free_space >= required_len) {
    690 
    691                                 /* Cut tail of current entry */
    692                                 ext4_directory_entry_ll_set_entry_length(dentry, used_space);
    693                                 ext4_directory_entry_ll_t *new_entry =
    694                                                 (void *)dentry + used_space;
    695                                 ext4_directory_write_entry(sb, new_entry,
    696                                                 free_space, child, name, name_len);
    697 
    698                                 target_block->dirty = true;
     630        uint32_t block_size = ext4_superblock_get_block_size(sb);
     631        uint16_t required_len = sizeof(ext4_fake_directory_entry_t) + name_len;
     632       
     633        if ((required_len % 4) != 0)
     634                required_len += 4 - (required_len % 4);
     635       
     636        /* Initialize pointers, stop means to upper bound */
     637        ext4_directory_entry_ll_t *dentry = target_block->data;
     638        ext4_directory_entry_ll_t *stop = target_block->data + block_size;
     639       
     640        /*
     641         * Walk through the block and check for invalid entries
     642         * or entries with free space for new entry
     643         */
     644        while (dentry < stop) {
     645                uint32_t inode = ext4_directory_entry_ll_get_inode(dentry);
     646                uint16_t rec_len = ext4_directory_entry_ll_get_entry_length(dentry);
     647               
     648                /* If invalid and large enough entry, use it */
     649                if ((inode == 0) && (rec_len >= required_len)) {
     650                        ext4_directory_write_entry(sb, dentry, rec_len, child,
     651                            name, name_len);
     652                        target_block->dirty = true;
     653                       
     654                        return EOK;
     655                }
     656               
     657                /* Valid entry, try to split it */
     658                if (inode != 0) {
     659                        uint16_t used_name_len =
     660                            ext4_directory_entry_ll_get_name_length(sb, dentry);
     661                       
     662                        uint16_t used_space =
     663                            sizeof(ext4_fake_directory_entry_t) + used_name_len;
     664                       
     665                        if ((used_name_len % 4) != 0)
     666                                used_space += 4 - (used_name_len % 4);
     667                       
     668                        uint16_t free_space = rec_len - used_space;
     669                       
     670                        /* There is free space for new entry */
     671                        if (free_space >= required_len) {
     672                                /* Cut tail of current entry */
     673                                ext4_directory_entry_ll_set_entry_length(dentry, used_space);
     674                                ext4_directory_entry_ll_t *new_entry =
     675                                    (void *) dentry + used_space;
     676                                ext4_directory_write_entry(sb, new_entry,
     677                                    free_space, child, name, name_len);
     678                               
     679                                target_block->dirty = true;
     680                               
    699681                                return EOK;
    700                         }
    701                 }
    702 
    703                 /* Jump to the next entry */
    704                 dentry = (void *)dentry + rec_len;
    705         }
    706 
    707         /* No free space found for new entry */
    708 
    709         return ENOSPC;
     682                        }
     683                }
     684               
     685                /* Jump to the next entry */
     686                dentry = (void *) dentry + rec_len;
     687        }
     688       
     689        /* No free space found for new entry */
     690        return ENOSPC;
    710691}
    711692
    712693/** Try to find entry in block by name.
    713694 *
    714  * @param block         block containing entries
    715  * @param sb            superblock
    716  * @param name_len      length of entry name
    717  * @param name          name of entry to be found
    718  * @param res_entry     output pointer to found entry, NULL if not found
    719  * @return                      error code
    720  */
    721 int ext4_directory_find_in_block(block_t *block,
    722                 ext4_superblock_t *sb, size_t name_len, const char *name,
    723                 ext4_directory_entry_ll_t **res_entry)
     695 * @param block     Block containing entries
     696 * @param sb        Superblock
     697 * @param name_len  Length of entry name
     698 * @param name      Name of entry to be found
     699 * @param res_entry Output pointer to found entry, NULL if not found
     700 *
     701 * @return Error code
     702 *
     703 */
     704int ext4_directory_find_in_block(block_t *block, ext4_superblock_t *sb,
     705    size_t name_len, const char *name, ext4_directory_entry_ll_t **res_entry)
    724706{
    725707        /* Start from the first entry in block */
    726         ext4_directory_entry_ll_t *dentry = (ext4_directory_entry_ll_t *)block->data;
    727         /*Set upper bound for cycling */
     708        ext4_directory_entry_ll_t *dentry =
     709            (ext4_directory_entry_ll_t *) block->data;
     710       
     711        /* Set upper bound for cycling */
    728712        uint8_t *addr_limit = block->data + ext4_superblock_get_block_size(sb);
    729 
     713       
    730714        /* Walk through the block and check entries */
    731         while ((uint8_t *)dentry < addr_limit) {
    732 
     715        while ((uint8_t *) dentry < addr_limit) {
    733716                /* Termination condition */
    734                 if ((uint8_t*) dentry + name_len > addr_limit) {
     717                if ((uint8_t *) dentry + name_len > addr_limit)
    735718                        break;
    736                 }
    737 
     719               
    738720                /* Valid entry - check it */
    739721                if (dentry->inode != 0) {
    740 
    741722                        /* For more effectivity compare firstly only lengths */
    742                         if (name_len == ext4_directory_entry_ll_get_name_length(sb, dentry)) {
     723                        if (ext4_directory_entry_ll_get_name_length(sb, dentry) ==
     724                            name_len) {
    743725                                /* Compare names */
    744                                 if (bcmp((uint8_t *)name, dentry->name, name_len) == 0) {
     726                                if (bcmp((uint8_t *) name, dentry->name, name_len) == 0) {
    745727                                        *res_entry = dentry;
    746728                                        return EOK;
     
    748730                        }
    749731                }
    750 
    751                 uint16_t dentry_len = ext4_directory_entry_ll_get_entry_length(dentry);
    752 
     732               
     733                uint16_t dentry_len =
     734                    ext4_directory_entry_ll_get_entry_length(dentry);
     735               
    753736                /* Corrupted entry */
    754                 if (dentry_len == 0) {
     737                if (dentry_len == 0)
    755738                        return EINVAL;
    756                 }
    757 
     739               
    758740                /* Jump to next entry */
    759                 dentry = (ext4_directory_entry_ll_t *)((uint8_t *)dentry + dentry_len);
    760         }
    761 
     741                dentry = (ext4_directory_entry_ll_t *) ((uint8_t *) dentry + dentry_len);
     742        }
     743       
    762744        /* Entry not found */
    763745        return ENOENT;
     
    766748/** Simple function to release allocated data from result.
    767749 *
    768  * @param result        search result to destroy
    769  * @return                      error code
     750 * @param result Search result to destroy
     751 *
     752 * @return Error code
     753 *
    770754 */
    771755int ext4_directory_destroy_result(ext4_directory_search_result_t *result)
    772756{
    773         if (result->block) {
     757        if (result->block)
    774758                return block_put(result->block);
    775         }
    776 
     759       
    777760        return EOK;
    778761}
  • uspace/lib/ext4/libext4_directory.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_DIRECTORY_H_
     
    3636#include "libext4_types.h"
    3737
    38 extern uint32_t ext4_directory_entry_ll_get_inode(ext4_directory_entry_ll_t *);
     38extern uint32_t ext4_directory_entry_ll_get_inode(ext4_directory_entry_ll_t *);
    3939extern void ext4_directory_entry_ll_set_inode(ext4_directory_entry_ll_t *,
    40                 uint32_t);
    41 extern uint16_t ext4_directory_entry_ll_get_entry_length(
     40    uint32_t);
     41extern uint16_t ext4_directory_entry_ll_get_entry_length(
    4242    ext4_directory_entry_ll_t *);
    43 extern void ext4_directory_entry_ll_set_entry_length(
    44                 ext4_directory_entry_ll_t *, uint16_t);
    45 extern uint16_t ext4_directory_entry_ll_get_name_length(
    46     ext4_superblock_t *, ext4_directory_entry_ll_t *);
     43extern void ext4_directory_entry_ll_set_entry_length(ext4_directory_entry_ll_t *,
     44    uint16_t);
     45extern uint16_t ext4_directory_entry_ll_get_name_length(ext4_superblock_t *,
     46    ext4_directory_entry_ll_t *);
    4747extern void ext4_directory_entry_ll_set_name_length(ext4_superblock_t *,
    48                 ext4_directory_entry_ll_t *, uint16_t);
     48    ext4_directory_entry_ll_t *, uint16_t);
    4949extern uint8_t ext4_directory_entry_ll_get_inode_type(ext4_superblock_t *,
    50                 ext4_directory_entry_ll_t *);
     50    ext4_directory_entry_ll_t *);
    5151extern void ext4_directory_entry_ll_set_inode_type(ext4_superblock_t *,
    52                 ext4_directory_entry_ll_t *, uint8_t);
     52    ext4_directory_entry_ll_t *, uint8_t);
    5353
    5454extern int ext4_directory_iterator_init(ext4_directory_iterator_t *,
    55                 ext4_inode_ref_t *, aoff64_t);
     55    ext4_inode_ref_t *, aoff64_t);
    5656extern int ext4_directory_iterator_next(ext4_directory_iterator_t *);
    5757extern int ext4_directory_iterator_fini(ext4_directory_iterator_t *);
    5858
    5959extern void ext4_directory_write_entry(ext4_superblock_t *,
    60                 ext4_directory_entry_ll_t *, uint16_t, ext4_inode_ref_t *,
    61                 const char *, size_t);
    62 extern int ext4_directory_add_entry(ext4_inode_ref_t *,
    63                 const char *, ext4_inode_ref_t *);
     60    ext4_directory_entry_ll_t *, uint16_t, ext4_inode_ref_t *,
     61    const char *, size_t);
     62extern int ext4_directory_add_entry(ext4_inode_ref_t *, const char *,
     63    ext4_inode_ref_t *);
    6464extern int ext4_directory_find_entry(ext4_directory_search_result_t *,
    65                 ext4_inode_ref_t *, const char *);
     65    ext4_inode_ref_t *, const char *);
    6666extern int ext4_directory_remove_entry(ext4_inode_ref_t *, const char *);
    6767
    68 extern int ext4_directory_try_insert_entry(ext4_superblock_t *,
    69                 block_t *, ext4_inode_ref_t *, const char *, uint32_t);
     68extern int ext4_directory_try_insert_entry(ext4_superblock_t *, block_t *,
     69    ext4_inode_ref_t *, const char *, uint32_t);
    7070
    71 extern int ext4_directory_find_in_block(block_t *,
    72                 ext4_superblock_t *, size_t, const char *,
    73                 ext4_directory_entry_ll_t **);
     71extern int ext4_directory_find_in_block(block_t *, ext4_superblock_t *, size_t,
     72    const char *, ext4_directory_entry_ll_t **);
    7473
    7574extern int ext4_directory_destroy_result(ext4_directory_search_result_t *);
     75
    7676#endif
    7777
  • uspace/lib/ext4/libext4_directory_index.c

    rb08e7970 r38542dc  
    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 */
  • uspace/lib/ext4/libext4_directory_index.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_DIRECTORY_INDEX_H_
     
    3737
    3838extern uint8_t ext4_directory_dx_root_info_get_hash_version(
    39                 ext4_directory_dx_root_info_t *);
     39    ext4_directory_dx_root_info_t *);
    4040extern void ext4_directory_dx_root_info_set_hash_version(
    41                 ext4_directory_dx_root_info_t *, uint8_t);
     41    ext4_directory_dx_root_info_t *, uint8_t);
    4242extern uint8_t ext4_directory_dx_root_info_get_info_length(
    43                 ext4_directory_dx_root_info_t *);
     43    ext4_directory_dx_root_info_t *);
    4444extern void ext4_directory_dx_root_info_set_info_length(
    45                 ext4_directory_dx_root_info_t *, uint8_t);
     45    ext4_directory_dx_root_info_t *, uint8_t);
    4646extern uint8_t ext4_directory_dx_root_info_get_indirect_levels(
    47                 ext4_directory_dx_root_info_t *);
     47    ext4_directory_dx_root_info_t *);
    4848extern void ext4_directory_dx_root_info_set_indirect_levels(
    49                 ext4_directory_dx_root_info_t *, uint8_t);
     49    ext4_directory_dx_root_info_t *, uint8_t);
    5050
    5151extern uint16_t ext4_directory_dx_countlimit_get_limit(
    52                 ext4_directory_dx_countlimit_t *);
     52    ext4_directory_dx_countlimit_t *);
    5353extern void ext4_directory_dx_countlimit_set_limit(
    54                 ext4_directory_dx_countlimit_t *, uint16_t);
     54    ext4_directory_dx_countlimit_t *, uint16_t);
    5555extern uint16_t ext4_directory_dx_countlimit_get_count(
    56                 ext4_directory_dx_countlimit_t *);
     56    ext4_directory_dx_countlimit_t *);
    5757extern void ext4_directory_dx_countlimit_set_count(
    58                 ext4_directory_dx_countlimit_t *, uint16_t);
     58    ext4_directory_dx_countlimit_t *, uint16_t);
    5959
    6060extern uint32_t ext4_directory_dx_entry_get_hash(ext4_directory_dx_entry_t *);
    6161extern void ext4_directory_dx_entry_set_hash(ext4_directory_dx_entry_t *,
    62                 uint32_t);
     62    uint32_t);
    6363extern uint32_t ext4_directory_dx_entry_get_block(ext4_directory_dx_entry_t *);
    64 void ext4_directory_dx_entry_set_block(ext4_directory_dx_entry_t *, uint32_t);
    65 
    66 /*********************************************************************************/
     64extern void ext4_directory_dx_entry_set_block(ext4_directory_dx_entry_t *,
     65    uint32_t);
    6766
    6867extern int ext4_directory_dx_init(ext4_inode_ref_t *);
    6968extern int ext4_directory_dx_find_entry(ext4_directory_search_result_t *,
    70                 ext4_inode_ref_t *, size_t, const char *);
    71 extern int ext4_directory_dx_add_entry(
    72                 ext4_inode_ref_t *, ext4_inode_ref_t *, const char *);
     69    ext4_inode_ref_t *, size_t, const char *);
     70extern int ext4_directory_dx_add_entry(ext4_inode_ref_t *, ext4_inode_ref_t *,
     71    const char *);
    7372
    7473#endif
  • uspace/lib/ext4/libext4_extent.c

    <
    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        libext4_extent.c
    35  * @brief       Ext4 extent structures operations.
     33 * @file  libext4_extent.c
     34 * @brief Ext4 extent structures operations.
    3635 */
    3736
     
    4342/** Get logical number of the block covered by extent.
    4443 *
    45  * @param extent        extent to load number from
    46  * @return                      logical number of the first block covered by extent
     44 * @param extent Extent to load number from
     45 *
     46 * @return Logical number of the first block covered by extent
     47 *
    4748 */
    4849uint32_t ext4_extent_get_first_block(ext4_extent_t *extent)
     
    5354/** Set logical number of the first block covered by extent.
    5455 *
    55  * @param extent        extent to set number to
    56  * @param iblock        logical number of the first block covered by extent
     56 * @param extent Extent to set number to
     57 * @param iblock Logical number of the first block covered by extent
     58 *
    5759 */
    5860void ext4_extent_set_first_block(ext4_extent_t *extent, uint32_t iblock)
     
    6365/** Get number of blocks covered by extent.
    6466 *
    65