Changeset 38542dc in mainline


Ignore:
Timestamp:
2012-08-12T18:36:10Z (12 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
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  * @param extent        extent to load count from
    66  * @return                      number of blocks covered by extent
     67 * @param extent Extent to load count from
     68 *
     69 * @return Number of blocks covered by extent
     70 *
    6771 */
    6872uint16_t ext4_extent_get_block_count(ext4_extent_t *extent)
     
    7377/** Set number of blocks covered by extent.
    7478 *
    75  * @param extent        extent to load count from
    76  * @param count         number of blocks covered by extent
     79 * @param extent Extent to load count from
     80 * @param count  Number of blocks covered by extent
     81 *
    7782 */
    7883void ext4_extent_set_block_count(ext4_extent_t *extent, uint16_t count)
     
    8388/** Get physical number of the first block covered by extent.
    8489 *
    85  * @param extent        extent to load number
    86  * @return                      physical number of the first block covered by extent
     90 * @param extent Extent to load number
     91 *
     92 * @return Physical number of the first block covered by extent
     93 *
    8794 */
    8895uint64_t ext4_extent_get_start(ext4_extent_t *extent)
    8996{
    9097        return ((uint64_t)uint16_t_le2host(extent->start_hi)) << 32 |
    91                         ((uint64_t)uint32_t_le2host(extent->start_lo));
     98            ((uint64_t)uint32_t_le2host(extent->start_lo));
    9299}
    93100
    94101/** Set physical number of the first block covered by extent.
    95102 *
    96  * @param extent        extent to load number
    97  * @param fblock        physical number of the first block covered by extent
     103 * @param extent Extent to load number
     104 * @param fblock Physical number of the first block covered by extent
     105 *
    98106 */
    99107void ext4_extent_set_start(ext4_extent_t *extent, uint64_t fblock)
     
    105113/** Get logical number of the block covered by extent index.
    106114 *
    107  * @param index         extent index to load number from
    108  * @return                      logical number of the first block covered by extent index
     115 * @param index Extent index to load number from
     116 *
     117 * @return Logical number of the first block covered by extent index
     118 *
    109119 */
    110120uint32_t ext4_extent_index_get_first_block(ext4_extent_index_t *index)
     
    115125/** Set logical number of the block covered by extent index.
    116126 *
    117  * @param index         extent index to set number to
    118  * @param iblock        logical number of the first block covered by extent index
     127 * @param index  Extent index to set number to
     128 * @param iblock Logical number of the first block covered by extent index
     129 *
    119130 */
    120131void ext4_extent_index_set_first_block(ext4_extent_index_t *index,
    121                 uint32_t iblock)
     132    uint32_t iblock)
    122133{
    123134        index->first_block = host2uint32_t_le(iblock);
     
    126137/** Get physical number of block where the child node is located.
    127138 *
    128  * @param index         extent index to load number from
    129  * @return                      physical number of the block with child node
     139 * @param index Extent index to load number from
     140 *
     141 * @return Physical number of the block with child node
     142 *
    130143 */
    131144uint64_t ext4_extent_index_get_leaf(ext4_extent_index_t *index)
    132145{
    133         return ((uint64_t)uint16_t_le2host(index->leaf_hi)) << 32 |
    134                 ((uint64_t)uint32_t_le2host(index->leaf_lo));
     146        return ((uint64_t) uint16_t_le2host(index->leaf_hi)) << 32 |
     147            ((uint64_t)uint32_t_le2host(index->leaf_lo));
    135148}
    136149
    137150/** Set physical number of block where the child node is located.
    138151 *
    139  * @param index         extent index to set number to
    140  * @param fblock        physical number of the block with child node
     152 * @param index  Extent index to set number to
     153 * @param fblock Ohysical number of the block with child node
     154 *
    141155 */
    142156void ext4_extent_index_set_leaf(ext4_extent_index_t *index, uint64_t fblock)
    143157{
    144158        index->leaf_lo = host2uint32_t_le((fblock << 32) >> 32);
    145         index->leaf_hi = host2uint16_t_le((uint16_t)(fblock >> 32));
     159        index->leaf_hi = host2uint16_t_le((uint16_t) (fblock >> 32));
    146160}
    147161
    148162/** Get magic value from extent header.
    149163 *
    150  * @param header        extent header to load value from
    151  * @return                      magic value of extent header
     164 * @param header Extent header to load value from
     165 *
     166 * @return Magic value of extent header
     167 *
    152168 */
    153169uint16_t ext4_extent_header_get_magic(ext4_extent_header_t *header)
     
    158174/** Set magic value to extent header.
    159175 *
    160  * @param header        extent header to set value to
    161  * @param magic         magic value of extent header
     176 * @param header Extent header to set value to
     177 * @param magic  Magic value of extent header
     178 *
    162179 */
    163180void ext4_extent_header_set_magic(ext4_extent_header_t *header, uint16_t magic)
     
    168185/** Get number of entries from extent header
    169186 *
    170  * @param header        extent header to get value from
    171  * @return                      number of entries covered by extent header
     187 * @param header Extent header to get value from
     188 *
     189 * @return Number of entries covered by extent header
     190 *
    172191 */
    173192uint16_t ext4_extent_header_get_entries_count(ext4_extent_header_t *header)
     
    178197/** Set number of entries to extent header
    179198 *
    180  * @param header        extent header to set value to
    181  * @param count         number of entries covered by extent header
     199 * @param header Extent header to set value to
     200 * @param count  Number of entries covered by extent header
     201 *
    182202 */
    183203void ext4_extent_header_set_entries_count(ext4_extent_header_t *header,
    184                 uint16_t count)
     204    uint16_t count)
    185205{
    186206        header->entries_count = host2uint16_t_le(count);
     
    189209/** Get maximum number of entries from extent header
    190210 *
    191  * @param header        extent header to get value from
    192  * @return                      maximum number of entries covered by extent header
     211 * @param header Extent header to get value from
     212 *
     213 * @return Maximum number of entries covered by extent header
     214 *
    193215 */
    194216uint16_t ext4_extent_header_get_max_entries_count(ext4_extent_header_t *header)
     
    199221/** Set maximum number of entries to extent header
    200222 *
    201  * @param header        extent header to set value to
    202  * @param max_count maximum number of entries covered by extent header
     223 * @param header    Extent header to set value to
     224 * @param max_count Maximum number of entries covered by extent header
     225 *
    203226 */
    204227void ext4_extent_header_set_max_entries_count(ext4_extent_header_t *header,
    205                 uint16_t max_count)
     228    uint16_t max_count)
    206229{
    207230        header->max_entries_count = host2uint16_t_le(max_count);
     
    210233/** Get depth of extent subtree.
    211234 *
    212  * @param header        extent header to get value from
    213  * @return                      depth of extent subtree
     235 * @param header Extent header to get value from
     236 *
     237 * @return Depth of extent subtree
     238 *
    214239 */
    215240uint16_t ext4_extent_header_get_depth(ext4_extent_header_t *header)
     
    220245/** Set depth of extent subtree.
    221246 *
    222  * @param header        extent header to set value to
    223  * @param depth         depth of extent subtree
     247 * @param header Extent header to set value to
     248 * @param depth  Depth of extent subtree
     249 *
    224250 */
    225251void ext4_extent_header_set_depth(ext4_extent_header_t *header, uint16_t depth)
     
    230256/** Get generation from extent header
    231257 *
    232  * @param header        extent header to get value from
    233  * @return                      generation
     258 * @param header Extent header to get value from
     259 *
     260 * @return Generation
     261 *
    234262 */
    235263uint32_t ext4_extent_header_get_generation(ext4_extent_header_t *header)
     
    240268/** Set generation to extent header
    241269 *
    242  * @param header                extent header to set value to
    243  * @param generation    generation
     270 * @param header     Extent header to set value to
     271 * @param generation Generation
     272 *
    244273 */
    245274void ext4_extent_header_set_generation(ext4_extent_header_t *header,
    246                 uint32_t generation)
     275    uint32_t generation)
    247276{
    248277        header->generation = host2uint32_t_le(generation);
     
    251280/** Binary search in extent index node.
    252281 *
    253  * @param header        extent header of index node
    254  * @param index         output value - found index will be set here
    255  * @param iblock        logical block number to find in index node
     282 * @param header Extent header of index node
     283 * @param index  Output value - found index will be set here
     284 * @param iblock Logical block number to find in index node
     285 *
    256286 */
    257287static void ext4_extent_binsearch_idx(ext4_extent_header_t *header,
    258         ext4_extent_index_t **index, uint32_t iblock)
    259 {
    260         ext4_extent_index_t *r, *l, *m;
    261 
    262         uint16_t entries_count = ext4_extent_header_get_entries_count(header);
    263 
     288    ext4_extent_index_t **index, uint32_t iblock)
     289{
     290        ext4_extent_index_t *r;
     291        ext4_extent_index_t *l;
     292        ext4_extent_index_t *m;
     293       
     294        uint16_t entries_count =
     295            ext4_extent_header_get_entries_count(header);
     296       
    264297        /* Initialize bounds */
    265298        l = EXT4_EXTENT_FIRST_INDEX(header) + 1;
    266299        r = EXT4_EXTENT_FIRST_INDEX(header) + entries_count - 1;
    267 
     300       
    268301        /* Do binary search */
    269302        while (l <= r) {
    270303                m = l + (r - l) / 2;
    271304                uint32_t first_block = ext4_extent_index_get_first_block(m);
    272                 if (iblock < first_block) {
    273                                 r = m - 1;
    274                 } else {
    275                                 l = m + 1;
    276                 }
    277         }
    278 
     305               
     306                if (iblock < first_block)
     307                        r = m - 1;
     308                else
     309                        l = m + 1;
     310        }
     311       
    279312        /* Set output value */
    280313        *index = l - 1;
     
    282315
    283316/** Binary search in extent leaf node.
    284  * @param header        extent header of leaf node
    285  * @param extent        output value - found extent will be set here,
    286  *                                      or NULL if node is empty
    287  * @param iblock        logical block number to find in leaf node
     317 *
     318 * @param header Extent header of leaf node
     319 * @param extent Output value - found extent will be set here,
     320 *               or NULL if node is empty
     321 * @param iblock Logical block number to find in leaf node
    288322 *
    289323 */
    290324static void ext4_extent_binsearch(ext4_extent_header_t *header,
    291                 ext4_extent_t **extent, uint32_t iblock)
    292 {
    293         ext4_extent_t *r, *l, *m;
    294 
    295         uint16_t entries_count = ext4_extent_header_get_entries_count(header);
    296 
     325    ext4_extent_t **extent, uint32_t iblock)
     326{
     327        ext4_extent_t *r;
     328        ext4_extent_t *l;
     329        ext4_extent_t *m;
     330       
     331        uint16_t entries_count =
     332            ext4_extent_header_get_entries_count(header);
     333       
    297334        if (entries_count == 0) {
    298335                /* this leaf is empty */
     
    300337                return;
    301338        }
    302 
     339       
    303340        /* Initialize bounds */
    304341        l = EXT4_EXTENT_FIRST(header) + 1;
    305342        r = EXT4_EXTENT_FIRST(header) + entries_count - 1;
    306 
     343       
    307344        /* Do binary search */
    308345        while (l <= r) {
    309346                m = l + (r - l) / 2;
    310347                uint32_t first_block = ext4_extent_get_first_block(m);
    311                 if (iblock < first_block) {
    312                                 r = m - 1;
    313                 } else {
    314                                 l = m + 1;
    315                 }
    316         }
    317 
     348               
     349                if (iblock < first_block)
     350                        r = m - 1;
     351                else
     352                        l = m + 1;
     353        }
     354       
    318355        /* Set output value */
    319356        *extent = l - 1;
     
    324361 * There is no need to save path in the tree during this algorithm.
    325362 *
    326  * @param inode_ref             i-node to load block from
    327  * @param iblock                logical block number to find
    328  * @param fblock                output value for physical block number
    329  * @return                              error code
    330  */
    331 int ext4_extent_find_block(ext4_inode_ref_t *inode_ref,
    332                 uint32_t iblock, uint32_t *fblock)
    333 {
    334         int rc;
    335 
     363 * @param inode_ref I-node to load block from
     364 * @param iblock    Logical block number to find
     365 * @param fblock    Output value for physical block number
     366 *
     367 * @return Error code
     368 *
     369 */
     370int ext4_extent_find_block(ext4_inode_ref_t *inode_ref, uint32_t iblock,
     371    uint32_t *fblock)
     372{
    336373        /* Compute bound defined by i-node size */
    337         uint64_t inode_size = ext4_inode_get_size(
    338                         inode_ref->fs->superblock, inode_ref->inode);
    339 
    340         uint32_t block_size = ext4_superblock_get_block_size(
    341                         inode_ref->fs->superblock);
    342 
     374        uint64_t inode_size =
     375            ext4_inode_get_size(inode_ref->fs->superblock, inode_ref->inode);
     376       
     377        uint32_t block_size =
     378            ext4_superblock_get_block_size(inode_ref->fs->superblock);
     379       
    343380        uint32_t last_idx = (inode_size - 1) / block_size;
    344 
     381       
    345382        /* Check if requested iblock is not over size of i-node */
    346383        if (iblock > last_idx) {
     
    348385                return EOK;
    349386        }
    350 
    351         block_t* block = NULL;
    352 
     387       
     388        block_t *block = NULL;
     389       
    353390        /* Walk through extent tree */
    354         ext4_extent_header_t *header = ext4_inode_get_extent_header(inode_ref->inode);
    355 
     391        ext4_extent_header_t *header =
     392            ext4_inode_get_extent_header(inode_ref->inode);
     393       
    356394        while (ext4_extent_header_get_depth(header) != 0) {
    357 
    358395                /* Search index in node */
    359396                ext4_extent_index_t *index;
    360397                ext4_extent_binsearch_idx(header, &index, iblock);
    361 
     398               
    362399                /* Load child node and set values for the next iteration */
    363400                uint64_t child = ext4_extent_index_get_leaf(index);
    364 
    365                 if (block != NULL) {
     401               
     402                if (block != NULL)
    366403                        block_put(block);
    367                 }
    368 
    369                 rc = block_get(&block, inode_ref->fs->device, child, BLOCK_FLAGS_NONE);
    370                 if (rc != EOK) {
     404               
     405                int rc = block_get(&block, inode_ref->fs->device, child,
     406                    BLOCK_FLAGS_NONE);
     407                if (rc != EOK)
    371408                        return rc;
    372                 }
    373 
     409               
    374410                header = (ext4_extent_header_t *)block->data;
    375411        }
    376 
     412       
    377413        /* Search extent in the leaf block */
    378414        ext4_extent_t* extent = NULL;
    379415        ext4_extent_binsearch(header, &extent, iblock);
    380 
     416       
    381417        /* Prevent empty leaf */
    382418        if (extent == NULL) {
    383419                *fblock = 0;
    384420        } else {
    385 
    386421                /* Compute requested physical block address */
    387422                uint32_t phys_block;
    388423                uint32_t first = ext4_extent_get_first_block(extent);
    389424                phys_block = ext4_extent_get_start(extent) + iblock - first;
    390 
     425               
    391426                *fblock = phys_block;
    392427        }
    393 
     428       
    394429        /* Cleanup */
    395         if (block != NULL) {
     430        if (block != NULL)
    396431                block_put(block);
    397         }
    398 
     432       
    399433        return EOK;
    400434}
    401 
    402435
    403436/** Find extent for specified iblock.
     
    406439 * saving the path through the tree for possible future modifications.
    407440 *
    408  * @param inode_ref             i-node to read extent tree from
    409  * @param iblock                iblock to find extent for
    410  * @param ret_path              output value for loaded path from extent tree
    411  * @return                              error code
    412  */
    413 static int ext4_extent_find_extent(ext4_inode_ref_t *inode_ref,
    414                 uint32_t iblock, ext4_extent_path_t **ret_path)
    415 {
    416         int rc;
    417 
     441 * @param inode_ref I-node to read extent tree from
     442 * @param iblock    Iblock to find extent for
     443 * @param ret_path  Output value for loaded path from extent tree
     444 *
     445 * @return Error code
     446 *
     447 */
     448static int ext4_extent_find_extent(ext4_inode_ref_t *inode_ref, uint32_t iblock,
     449    ext4_extent_path_t **ret_path)
     450{
    418451        ext4_extent_header_t *eh =
    419                         ext4_inode_get_extent_header(inode_ref->inode);
    420 
     452            ext4_inode_get_extent_header(inode_ref->inode);
     453       
    421454        uint16_t depth = ext4_extent_header_get_depth(eh);
    422 
     455       
    423456        ext4_extent_path_t *tmp_path;
    424 
     457       
    425458        /* Added 2 for possible tree growing */
    426459        tmp_path = malloc(sizeof(ext4_extent_path_t) * (depth + 2));
    427         if (tmp_path == NULL) {
     460        if (tmp_path == NULL)
    428461                return ENOMEM;
    429         }
    430 
     462       
    431463        /* Initialize structure for algorithm start */
    432464        tmp_path[0].block = inode_ref->block;
    433465        tmp_path[0].header = eh;
    434 
     466       
    435467        /* Walk through the extent tree */
    436468        uint16_t pos = 0;
     469        int rc;
    437470        while (ext4_extent_header_get_depth(eh) != 0) {
    438 
    439471                /* Search index in index node by iblock */
    440                 ext4_extent_binsearch_idx(tmp_path[pos].header, &tmp_path[pos].index, iblock);
    441 
     472                ext4_extent_binsearch_idx(tmp_path[pos].header,
     473                    &tmp_path[pos].index, iblock);
     474               
    442475                tmp_path[pos].depth = depth;
    443476                tmp_path[pos].extent = NULL;
    444 
     477               
    445478                assert(tmp_path[pos].index != NULL);
    446 
     479               
    447480                /* Load information for the next iteration */
    448481                uint64_t fblock = ext4_extent_index_get_leaf(tmp_path[pos].index);
    449 
     482               
    450483                block_t *block;
    451                 rc = block_get(&block, inode_ref->fs->device, fblock, BLOCK_FLAGS_NONE);
    452                 if (rc != EOK) {
     484                rc = block_get(&block, inode_ref->fs->device, fblock,
     485                    BLOCK_FLAGS_NONE);
     486                if (rc != EOK)
    453487                        goto cleanup;
    454                 }
    455 
     488               
    456489                pos++;
    457 
     490               
    458491                eh = (ext4_extent_header_t *)block->data;
    459492                tmp_path[pos].block = block;
    460493                tmp_path[pos].header = eh;
    461 
    462         }
    463 
     494        }
     495       
    464496        tmp_path[pos].depth = 0;
    465497        tmp_path[pos].extent = NULL;
    466498        tmp_path[pos].index = NULL;
    467 
    468     /* Find extent in the leaf node */
     499       
     500        /* Find extent in the leaf node */
    469501        ext4_extent_binsearch(tmp_path[pos].header, &tmp_path[pos].extent, iblock);
    470 
    471502        *ret_path = tmp_path;
    472 
     503       
    473504        return EOK;
    474 
     505       
    475506cleanup:
    476         /* Put loaded blocks
     507        /*
     508         * Put loaded blocks
    477509         * From 1: 0 is a block with inode data
    478510         */
    479511        for (uint16_t i = 1; i < tmp_path->depth; ++i) {
    480                 if (tmp_path[i].block) {
     512                if (tmp_path[i].block)
    481513                        block_put(tmp_path[i].block);
    482                 }
    483         }
    484 
     514        }
     515       
    485516        /* Destroy temporary data structure */
    486517        free(tmp_path);
    487 
     518       
    488519        return rc;
    489520}
     
    491522/** Release extent and all data blocks covered by the extent.
    492523 *
    493  * @param inode_ref             i-node to release extent and block from
    494  * @param extent                extent to release
    495  * @return                              error code
    496  */
    497 static int ext4_extent_release(
    498                 ext4_inode_ref_t *inode_ref, ext4_extent_t *extent)
    499 {
    500         int rc;
    501 
     524 * @param inode_ref I-node to release extent and block from
     525 * @param extent    Extent to release
     526 *
     527 * @return Error code
     528 *
     529 */
     530static int ext4_extent_release(ext4_inode_ref_t *inode_ref,
     531    ext4_extent_t *extent)
     532{
    502533        /* Compute number of the first physical block to release */
    503534        uint64_t start = ext4_extent_get_start(extent);
    504535        uint16_t block_count = ext4_extent_get_block_count(extent);
    505 
    506         rc = ext4_balloc_free_blocks(inode_ref, start, block_count);
    507         if (rc != EOK) {
    508                 return rc;
    509         }
    510 
    511         return EOK;
     536       
     537        return ext4_balloc_free_blocks(inode_ref, start, block_count);
    512538}
    513539
     
    517543 * the node. In the leaf node all extents will be released.
    518544 *
    519  * @param inode_ref             i-node where the branch is released
    520  * @param index                 index in the non-leaf node to be released
    521  *                                              with the whole subtree
    522  * @return                              error code
     545 * @param inode_ref I-node where the branch is released
     546 * @param index     Index in the non-leaf node to be released
     547 *                  with the whole subtree
     548 *
     549 * @return Error code
     550 *
    523551 */
    524552static int ext4_extent_release_branch(ext4_inode_ref_t *inode_ref,
    525553                ext4_extent_index_t *index)
    526554{
    527         int rc;
    528 
     555        uint32_t fblock = ext4_extent_index_get_leaf(index);
     556       
    529557        block_t* block;
    530 
    531         uint32_t fblock = ext4_extent_index_get_leaf(index);
    532 
    533         rc = block_get(&block, inode_ref->fs->device, fblock, BLOCK_FLAGS_NONE);
    534         if (rc != EOK) {
     558        int rc = block_get(&block, inode_ref->fs->device, fblock, BLOCK_FLAGS_NONE);
     559        if (rc != EOK)
    535560                return rc;
    536         }
    537 
     561       
    538562        ext4_extent_header_t *header = block->data;
    539 
     563       
    540564        if (ext4_extent_header_get_depth(header)) {
    541 
    542565                /* The node is non-leaf, do recursion */
    543 
    544566                ext4_extent_index_t *idx = EXT4_EXTENT_FIRST_INDEX(header);
    545 
     567               
    546568                /* Release all subbranches */
    547                 for (uint32_t i = 0; i < ext4_extent_header_get_entries_count(header); ++i, ++idx) {
     569                for (uint32_t i = 0;
     570                    i < ext4_extent_header_get_entries_count(header);
     571                    ++i, ++idx) {
    548572                        rc = ext4_extent_release_branch(inode_ref, idx);
    549                         if (rc != EOK) {
     573                        if (rc != EOK)
    550574                                return rc;
    551                         }
    552575                }
    553576        } else {
    554 
    555577                /* Leaf node reached */
    556578                ext4_extent_t *ext = EXT4_EXTENT_FIRST(header);
    557 
     579               
    558580                /* Release all extents and stop recursion */
    559 
    560                 for (uint32_t i = 0; i < ext4_extent_header_get_entries_count(header); ++i, ++ext) {
     581                for (uint32_t i = 0;
     582                    i < ext4_extent_header_get_entries_count(header);
     583                    ++i, ++ext) {
    561584                        rc = ext4_extent_release(inode_ref, ext);
    562                         if (rc != EOK) {
     585                        if (rc != EOK)
    563586                                return rc;
    564                         }
    565587                }
    566588        }
    567 
     589       
    568590        /* Release data block where the node was stored */
    569 
     591       
    570592        rc = block_put(block);
    571         if (rc != EOK) {
     593        if (rc != EOK)
    572594                return rc;
    573         }
    574 
     595       
    575596        ext4_balloc_free_block(inode_ref, fblock);
    576 
     597       
    577598        return EOK;
    578599}
     
    580601/** Release all data blocks starting from specified logical block.
    581602 *
    582  * @param inode_ref             i-node to release blocks from
    583  * @param iblock_from   first logical block to release
     603 * @param inode_ref   I-node to release blocks from
     604 * @param iblock_from First logical block to release
     605 *
    584606 */
    585607int ext4_extent_release_blocks_from(ext4_inode_ref_t *inode_ref,
    586                 uint32_t iblock_from)
    587 {
    588         int rc = EOK;
    589 
     608    uint32_t iblock_from)
     609{
    590610        /* Find the first extent to modify */
    591611        ext4_extent_path_t *path;
    592         rc = ext4_extent_find_extent(inode_ref, iblock_from, &path);
    593         if (rc != EOK) {
     612        int rc = ext4_extent_find_extent(inode_ref, iblock_from, &path);
     613        if (rc != EOK)
    594614                return rc;
    595         }
    596 
     615       
    597616        /* Jump to last item of the path (extent) */
    598617        ext4_extent_path_t *path_ptr = path;
    599         while (path_ptr->depth != 0) {
     618        while (path_ptr->depth != 0)
    600619                path_ptr++;
    601         }
    602 
     620       
    603621        assert(path_ptr->extent != NULL);
    604 
     622       
    605623        /* First extent maybe released partially */
    606         uint32_t first_iblock = ext4_extent_get_first_block(path_ptr->extent);
    607         uint32_t first_fblock = ext4_extent_get_start(path_ptr->extent) + iblock_from - first_iblock;
    608 
    609 
     624        uint32_t first_iblock =
     625            ext4_extent_get_first_block(path_ptr->extent);
     626        uint32_t first_fblock =
     627            ext4_extent_get_start(path_ptr->extent) + iblock_from - first_iblock;
     628       
    610629        uint16_t block_count = ext4_extent_get_block_count(path_ptr->extent);
    611 
    612         uint16_t delete_count = block_count - (
    613                         ext4_extent_get_start(path_ptr->extent) - first_fblock);
    614 
     630       
     631        uint16_t delete_count = block_count -
     632            (ext4_extent_get_start(path_ptr->extent) - first_fblock);
     633       
    615634        /* Release all blocks */
    616635        rc = ext4_balloc_free_blocks(inode_ref, first_fblock, delete_count);
    617         if (rc != EOK) {
     636        if (rc != EOK)
    618637                goto cleanup;
    619         }
    620 
     638       
    621639        /* Correct counter */
    622640        block_count -= delete_count;
    623641        ext4_extent_set_block_count(path_ptr->extent, block_count);
    624 
     642       
    625643        /* Initialize the following loop */
    626         uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
     644        uint16_t entries =
     645            ext4_extent_header_get_entries_count(path_ptr->header);
    627646        ext4_extent_t *tmp_ext = path_ptr->extent + 1;
    628647        ext4_extent_t *stop_ext = EXT4_EXTENT_FIRST(path_ptr->header) + entries;
    629 
     648       
    630649        /* If first extent empty, release it */
    631         if (block_count == 0) {
     650        if (block_count == 0)
    632651                entries--;
    633         }
    634 
     652       
    635653        /* Release all successors of the first extent in the same node */
    636654        while (tmp_ext < stop_ext) {
    637655                first_fblock = ext4_extent_get_start(tmp_ext);
    638656                delete_count = ext4_extent_get_block_count(tmp_ext);
    639 
     657               
    640658                rc = ext4_balloc_free_blocks(inode_ref, first_fblock, delete_count);
    641                 if (rc != EOK) {
     659                if (rc != EOK)
    642660                        goto cleanup;
    643                 }
    644 
     661               
    645662                entries--;
    646663                tmp_ext++;
    647664        }
    648 
     665       
    649666        ext4_extent_header_set_entries_count(path_ptr->header, entries);
    650667        path_ptr->block->dirty = true;
    651 
     668       
    652669        /* If leaf node is empty, parent entry must be modified */
    653670        bool remove_parent_record = false;
    654 
     671       
    655672        /* Don't release root block (including inode data) !!! */
    656673        if ((path_ptr != path) && (entries == 0)) {
    657674                rc = ext4_balloc_free_block(inode_ref, path_ptr->block->lba);
    658                 if (rc != EOK) {
     675                if (rc != EOK)
    659676                        goto cleanup;
    660                 }
     677               
    661678                remove_parent_record = true;
    662679        }
    663 
     680       
    664681        /* Jump to the parent */
    665682        --path_ptr;
    666 
     683       
    667684        /* Release all successors in all tree levels */
    668685        while (path_ptr >= path) {
     
    670687                ext4_extent_index_t *index = path_ptr->index + 1;
    671688                ext4_extent_index_t *stop =
    672                                 EXT4_EXTENT_FIRST_INDEX(path_ptr->header) + entries;
    673 
     689                    EXT4_EXTENT_FIRST_INDEX(path_ptr->header) + entries;
     690               
    674691                /* Correct entries count because of changes in the previous iteration */
    675                 if (remove_parent_record) {
     692                if (remove_parent_record)
    676693                        entries--;
    677                 }
    678 
     694               
    679695                /* Iterate over all entries and release the whole subtrees */
    680696                while (index < stop) {
    681697                        rc = ext4_extent_release_branch(inode_ref, index);
    682                         if (rc != EOK) {
     698                        if (rc != EOK)
    683699                                goto cleanup;
    684                         }
     700                       
    685701                        ++index;
    686702                        --entries;
    687703                }
    688 
     704               
    689705                ext4_extent_header_set_entries_count(path_ptr->header, entries);
    690706                path_ptr->block->dirty = true;
    691 
     707               
    692708                /* Free the node if it is empty */
    693709                if ((entries == 0) && (path_ptr != path)) {
    694710                        rc = ext4_balloc_free_block(inode_ref, path_ptr->block->lba);
    695                         if (rc != EOK) {
     711                        if (rc != EOK)
    696712                                goto cleanup;
    697                         }
    698 
     713                       
    699714                        /* Mark parent to be checked */
    700715                        remove_parent_record = true;
    701                 } else {
     716                } else
    702717                        remove_parent_record = false;
    703                 }
    704 
     718               
    705719                --path_ptr;
    706720        }
    707 
    708 
     721       
    709722cleanup:
    710         /* Put loaded blocks
     723        /*
     724         * Put loaded blocks
    711725         * starting from 1: 0 is a block with inode data
    712726         */
    713727        for (uint16_t i = 1; i <= path->depth; ++i) {
    714                 if (path[i].block) {
     728                if (path[i].block)
    715729                        block_put(path[i].block);
    716                 }
    717         }
    718 
     730        }
     731       
    719732        /* Destroy temporary data structure */
    720733        free(path);
    721 
     734       
    722735        return rc;
    723736}
    724737
    725 
    726738/** Append new extent to the i-node and do some splitting if necessary.
    727739 *
    728  * @param inode_ref                     i-node to append extent to
    729  * @param path                          path in the extent tree for possible splitting
    730  * @param last_path_item        input/output parameter for pointer to the last
    731  *                                                      valid item in the extent tree path
    732  * @param iblock                        logical index of block to append extent for
    733  * @return                                      error code
     740 * @param inode_ref      I-node to append extent to
     741 * @param path           Path in the extent tree for possible splitting
     742 * @param last_path_item Input/output parameter for pointer to the last
     743 *                       valid item in the extent tree path
     744 * @param iblock         Logical index of block to append extent for
     745 *
     746 * @return Error code
     747 *
    734748 */
    735749static int ext4_extent_append_extent(ext4_inode_ref_t *inode_ref,
    736                 ext4_extent_path_t *path, uint32_t iblock)
    737 {
    738         int rc;
    739 
     750    ext4_extent_path_t *path, uint32_t iblock)
     751{
    740752        ext4_extent_path_t *path_ptr = path + path->depth;
    741 
     753       
    742754        uint32_t block_size =
    743                         ext4_superblock_get_block_size(inode_ref->fs->superblock);
    744 
     755            ext4_superblock_get_block_size(inode_ref->fs->superblock);
     756       
    745757        /* Start splitting */
    746758        while (path_ptr > path) {
    747 
    748                 uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
    749                 uint16_t limit = ext4_extent_header_get_max_entries_count(path_ptr->header);
    750 
     759                uint16_t entries =
     760                    ext4_extent_header_get_entries_count(path_ptr->header);
     761                uint16_t limit =
     762                    ext4_extent_header_get_max_entries_count(path_ptr->header);
     763               
    751764                if (entries == limit) {
    752 
    753765                        /* Full node - allocate block for new one */
    754766                        uint32_t fblock;
    755                         rc = ext4_balloc_alloc_block(inode_ref, &fblock);
    756                         if (rc != EOK) {
     767                        int rc = ext4_balloc_alloc_block(inode_ref, &fblock);
     768                        if (rc != EOK)
    757769                                return rc;
    758                         }
    759 
     770                       
    760771                        block_t *block;
    761                         rc = block_get(&block, inode_ref->fs->device, fblock, BLOCK_FLAGS_NOREAD);
     772                        rc = block_get(&block, inode_ref->fs->device, fblock,
     773                            BLOCK_FLAGS_NOREAD);
    762774                        if (rc != EOK) {
    763775                                ext4_balloc_free_block(inode_ref, fblock);
    764776                                return rc;
    765777                        }
    766 
     778                       
    767779                        /* Put back not modified old block */
    768780                        block_put(path_ptr->block);
    769 
     781                       
    770782                        /* Initialize newly allocated block and remember it */
    771783                        memset(block->data, 0, block_size);
    772784                        path_ptr->block = block;
    773 
     785                       
    774786                        /* Update pointers in extent path structure */
    775787                        path_ptr->header = block->data;
     
    779791                                ext4_extent_index_set_leaf(path_ptr->index, (path_ptr + 1)->block->lba);
    780792                                limit = (block_size - sizeof(ext4_extent_header_t)) /
    781                                                                         sizeof(ext4_extent_index_t);
     793                                    sizeof(ext4_extent_index_t);
    782794                        } else {
    783795                                path_ptr->extent = EXT4_EXTENT_FIRST(path_ptr->header);
    784796                                ext4_extent_set_first_block(path_ptr->extent, iblock);
    785797                                limit = (block_size - sizeof(ext4_extent_header_t)) /
    786                                                                         sizeof(ext4_extent_t);
     798                                    sizeof(ext4_extent_t);
    787799                        }
    788 
     800                       
    789801                        /* Initialize on-disk structure (header) */
    790802                        ext4_extent_header_set_entries_count(path_ptr->header, 1);
     
    793805                        ext4_extent_header_set_depth(path_ptr->header, path_ptr->depth);
    794806                        ext4_extent_header_set_generation(path_ptr->header, 0);
    795 
     807                       
    796808                        path_ptr->block->dirty = true;
    797 
     809                       
    798810                        /* Jump to the preceeding item */
    799811                        path_ptr--;
    800 
    801812                } else {
    802 
    803813                        /* Node with free space */
    804814                        if (path_ptr->depth) {
     
    810820                                ext4_extent_set_first_block(path_ptr->extent, iblock);
    811821                        }
    812 
     822                       
    813823                        ext4_extent_header_set_entries_count(path_ptr->header, entries + 1);
    814824                        path_ptr->block->dirty = true;
    815 
     825                       
    816826                        /* No more splitting needed */
    817827                        return EOK;
    818828                }
    819 
    820         }
    821 
     829        }
     830       
    822831        assert(path_ptr == path);
    823 
     832       
    824833        /* Should be the root split too? */
    825 
     834       
    826835        uint16_t entries = ext4_extent_header_get_entries_count(path->header);
    827836        uint16_t limit = ext4_extent_header_get_max_entries_count(path->header);
    828 
     837       
    829838        if (entries == limit) {
    830 
    831839                uint32_t new_fblock;
    832                 rc = ext4_balloc_alloc_block(inode_ref, &new_fblock);
    833                 if (rc != EOK) {
     840                int rc = ext4_balloc_alloc_block(inode_ref, &new_fblock);
     841                if (rc != EOK)
    834842                        return rc;
    835                 }
    836 
     843               
    837844                block_t *block;
    838                 rc = block_get(&block, inode_ref->fs->device,
    839                                 new_fblock, BLOCK_FLAGS_NOREAD);
    840                 if (rc != EOK) {
     845                rc = block_get(&block, inode_ref->fs->device, new_fblock,
     846                    BLOCK_FLAGS_NOREAD);
     847                if (rc != EOK)
    841848                        return rc;
    842                 }
    843 
     849               
    844850                /* Initialize newly allocated block */
    845851                memset(block->data, 0, block_size);
    846 
     852               
    847853                /* Move data from root to the new block */
    848854                memcpy(block->data, inode_ref->inode->blocks,
    849                                 EXT4_INODE_BLOCKS * sizeof(uint32_t));
    850 
    851                 // Data block initialized !!!
    852 
     855                    EXT4_INODE_BLOCKS * sizeof(uint32_t));
     856               
     857                /* Data block is initialized */
     858               
    853859                block_t *root_block = path->block;
    854860                uint16_t root_depth = path->depth;
    855861                ext4_extent_header_t *root_header = path->header;
    856 
     862               
    857863                /* Make space for tree growing */
    858864                ext4_extent_path_t *new_root = path;
    859865                ext4_extent_path_t *old_root = path + 1;
    860 
     866               
    861867                size_t nbytes = sizeof(ext4_extent_path_t) * (path->depth + 1);
    862868                memmove(old_root, new_root, nbytes);
    863869                memset(new_root, 0, sizeof(ext4_extent_path_t));
    864 
     870               
    865871                /* Update old root structure */
    866872                old_root->block = block;
    867873                old_root->header = (ext4_extent_header_t *)block->data;
    868 
     874               
    869875                /* Add new entry and update limit for entries */
    870876                if (old_root->depth) {
    871877                        limit = (block_size - sizeof(ext4_extent_header_t)) /
    872                                                                 sizeof(ext4_extent_index_t);
     878                            sizeof(ext4_extent_index_t);
    873879                        old_root->index = EXT4_EXTENT_FIRST_INDEX(old_root->header) + entries;
    874880                        ext4_extent_index_set_first_block(old_root->index, iblock);
     
    877883                } else {
    878884                        limit = (block_size - sizeof(ext4_extent_header_t)) /
    879                                                                 sizeof(ext4_extent_t);
     885                            sizeof(ext4_extent_t);
    880886                        old_root->extent = EXT4_EXTENT_FIRST(old_root->header) + entries;
    881887                        ext4_extent_set_first_block(old_root->extent, iblock);
    882888                        old_root->index = NULL;
    883889                }
     890               
    884891                ext4_extent_header_set_entries_count(old_root->header, entries + 1);
    885892                ext4_extent_header_set_max_entries_count(old_root->header, limit);
    886 
     893               
    887894                old_root->block->dirty = true;
    888 
     895               
    889896                /* Re-initialize new root metadata */
    890897                new_root->depth = root_depth + 1;
     
    893900                new_root->extent = NULL;
    894901                new_root->index = EXT4_EXTENT_FIRST_INDEX(new_root->header);
    895 
     902               
    896903                ext4_extent_header_set_depth(new_root->header, new_root->depth);
    897 
     904               
    898905                /* Create new entry in root */
    899906                ext4_extent_header_set_entries_count(new_root->header, 1);
    900907                ext4_extent_index_set_first_block(new_root->index, 0);
    901908                ext4_extent_index_set_leaf(new_root->index, new_fblock);
    902 
     909               
    903910                new_root->block->dirty = true;
    904 
    905911        } else {
    906 
    907912                if (path->depth) {
    908913                        path->index = EXT4_EXTENT_FIRST_INDEX(path->header) + entries;
     
    913918                        ext4_extent_set_first_block(path->extent, iblock);
    914919                }
    915 
     920               
    916921                ext4_extent_header_set_entries_count(path->header, entries + 1);
    917922                path->block->dirty = true;
    918923        }
    919 
     924       
    920925        return EOK;
    921926}
     
    927932 * It includes possible extent tree modifications (splitting).
    928933 *<
    929  * @param inode_ref                     i-node to append block to
    930  * @param iblock                        output logical number of newly allocated block
    931  * @param fblock                        output physical block address of newly allocated block
    932  * @return                                      error code
    933  */
    934 int ext4_extent_append_block(ext4_inode_ref_t *inode_ref,
    935                 uint32_t *iblock, uint32_t *fblock, bool update_size)
    936 {
    937         int rc = EOK;
    938 
     934 * @param inode_ref I-node to append block to
     935 * @param iblock    Output logical number of newly allocated block
     936 * @param fblock    Output physical block address of newly allocated block
     937 *
     938 * @return Error code
     939 *
     940 */
     941int ext4_extent_append_block(ext4_inode_ref_t *inode_ref, uint32_t *iblock,
     942    uint32_t *fblock, bool update_size)
     943{
    939944        ext4_superblock_t *sb = inode_ref->fs->superblock;
    940945        uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
    941946        uint32_t block_size = ext4_superblock_get_block_size(sb);
    942 
     947       
    943948        /* Calculate number of new logical block */
    944949        uint32_t new_block_idx = 0;
    945950        if (inode_size > 0) {
    946                 if ((inode_size % block_size) != 0) {
     951                if ((inode_size % block_size) != 0)
    947952                        inode_size += block_size - (inode_size % block_size);
    948                 }
     953               
    949954                new_block_idx = inode_size / block_size;
    950955        }
    951 
     956       
    952957        /* Load the nearest leaf (with extent) */
    953958        ext4_extent_path_t *path;
    954         rc = ext4_extent_find_extent(inode_ref, new_block_idx, &path);
    955         if (rc != EOK) {
     959        int rc = ext4_extent_find_extent(inode_ref, new_block_idx, &path);
     960        if (rc != EOK)
    956961                return rc;
    957         }
    958 
     962       
    959963        /* Jump to last item of the path (extent) */
    960964        ext4_extent_path_t *path_ptr = path;
    961         while (path_ptr->depth != 0) {
     965        while (path_ptr->depth != 0)
    962966                path_ptr++;
    963         }
    964 
     967       
    965968        /* Add new extent to the node if not present */
    966         if (path_ptr->extent == NULL) {
     969        if (path_ptr->extent == NULL)
    967970                goto append_extent;
    968         }
    969 
     971       
    970972        uint16_t block_count = ext4_extent_get_block_count(path_ptr->extent);
    971973        uint16_t block_limit = (1 << 15);
    972 
     974       
    973975        uint32_t phys_block = 0;
    974976        if (block_count < block_limit) {
    975 
    976977                /* There is space for new block in the extent */
    977 
    978978                if (block_count == 0) {
    979 
    980979                        /* Existing extent is empty */
    981 
    982980                        rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
    983                         if (rc != EOK) {
     981                        if (rc != EOK)
    984982                                goto finish;
    985                         }
    986 
     983                       
    987984                        /* Initialize extent */
    988985                        ext4_extent_set_first_block(path_ptr->extent, new_block_idx);
    989986                        ext4_extent_set_start(path_ptr->extent, phys_block);
    990987                        ext4_extent_set_block_count(path_ptr->extent, 1);
    991 
     988                       
    992989                        /* Update i-node */
    993990                        if (update_size) {
     
    995992                                inode_ref->dirty = true;
    996993                        }
    997 
     994                       
    998995                        path_ptr->block->dirty = true;
    999 
     996                       
    1000997                        goto finish;
    1001998                } else {
    1002 
    1003999                        /* Existing extent contains some blocks */
    1004 
    10051000                        phys_block = ext4_extent_get_start(path_ptr->extent);
    10061001                        phys_block += ext4_extent_get_block_count(path_ptr->extent);
    1007 
     1002                       
    10081003                        /* Check if the following block is free for allocation */
    10091004                        bool free;
    10101005                        rc = ext4_balloc_try_alloc_block(inode_ref, phys_block, &free);
    1011                         if (rc != EOK) {
     1006                        if (rc != EOK)
    10121007                                goto finish;
    1013                         }
    1014 
    1015                         if (! free) {
    1016                                 /* target is not free, new block must be appended to new extent */
     1008                       
     1009                        if (!free) {
     1010                                /* Target is not free, new block must be appended to new extent */
    10171011                                goto append_extent;
    10181012                        }
    1019 
    1020 
     1013                       
    10211014                        /* Update extent */
    10221015                        ext4_extent_set_block_count(path_ptr->extent, block_count + 1);
    1023 
     1016                       
    10241017                        /* Update i-node */
    10251018                        if (update_size) {
     
    10271020                                inode_ref->dirty = true;
    10281021                        }
    1029 
     1022                       
    10301023                        path_ptr->block->dirty = true;
    1031 
     1024                       
    10321025                        goto finish;
    10331026                }
    10341027        }
    1035 
    1036 /* Append new extent to the tree */
     1028       
     1029       
    10371030append_extent:
    1038 
     1031        /* Append new extent to the tree */
    10391032        phys_block = 0;
    1040 
     1033       
    10411034        /* Allocate new data block */
    10421035        rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
    1043         if (rc != EOK) {
     1036        if (rc != EOK)
    10441037                goto finish;
    1045         }
    1046 
     1038       
    10471039        /* Append extent for new block (includes tree splitting if needed) */
    10481040        rc = ext4_extent_append_extent(inode_ref, path, new_block_idx);
     
    10511043                goto finish;
    10521044        }
    1053 
     1045       
    10541046        uint32_t tree_depth = ext4_extent_header_get_depth(path->header);
    10551047        path_ptr = path + tree_depth;
    1056 
     1048       
    10571049        /* Initialize newly created extent */
    10581050        ext4_extent_set_block_count(path_ptr->extent, 1);
    10591051        ext4_extent_set_first_block(path_ptr->extent, new_block_idx);
    10601052        ext4_extent_set_start(path_ptr->extent, phys_block);
    1061 
     1053       
    10621054        /* Update i-node */
    10631055        if (update_size) {
     
    10651057                inode_ref->dirty = true;
    10661058        }
    1067 
     1059       
    10681060        path_ptr->block->dirty = true;
    1069 
    1070 
     1061       
    10711062finish:
    10721063        /* Set return values */
    10731064        *iblock = new_block_idx;
    10741065        *fblock = phys_block;
    1075 
    1076         /* Put loaded blocks
     1066       
     1067        /*
     1068         * Put loaded blocks
    10771069         * starting from 1: 0 is a block with inode data
    10781070         */
    10791071        for (uint16_t i = 1; i <= path->depth; ++i) {
    1080                 if (path[i].block) {
     1072                if (path[i].block)
    10811073                        block_put(path[i].block);
    1082                 }
    1083         }
    1084 
     1074        }
     1075       
    10851076        /* Destroy temporary data structure */
    10861077        free(path);
    1087 
     1078       
    10881079        return rc;
    10891080}
     
    10911082/**
    10921083 * @}
    1093  */ 
     1084 */
  • uspace/lib/ext4/libext4_extent.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_EXTENT_H_
     
    5252extern uint16_t ext4_extent_header_get_entries_count(ext4_extent_header_t *);
    5353extern void ext4_extent_header_set_entries_count(ext4_extent_header_t *,
    54                 uint16_t);
     54    uint16_t);
    5555extern uint16_t ext4_extent_header_get_max_entries_count(ext4_extent_header_t *);
    5656extern void ext4_extent_header_set_max_entries_count(ext4_extent_header_t *,
    57                 uint16_t);
     57    uint16_t);
    5858extern uint16_t ext4_extent_header_get_depth(ext4_extent_header_t *);
    5959extern void ext4_extent_header_set_depth(ext4_extent_header_t *, uint16_t);
     
    6464extern int ext4_extent_release_blocks_from(ext4_inode_ref_t *, uint32_t);
    6565
    66 extern int ext4_extent_append_block(ext4_inode_ref_t *, uint32_t *, uint32_t *, bool);
     66extern int ext4_extent_append_block(ext4_inode_ref_t *, uint32_t *, uint32_t *,
     67    bool);
    6768
    6869#endif
  • uspace/lib/ext4/libext4_filesystem.c

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        libext4_filesystem.c
    35  * @brief       More complex filesystem operations.
     33 * @file  libext4_filesystem.c
     34 * @brief More complex filesystem operations.
    3635 */
    3736
     
    4342/** Initialize filesystem and read all needed data.
    4443 *
    45  * @param fs                            filesystem instance to be initialized
    46  * @param service_id            identifier if device with the filesystem
    47  * @return                                      error code
     44 * @param fs         Filesystem instance to be initialized
     45 * @param service_id Identifier if device with the filesystem
     46 *
     47 * @return Error code
     48 *
    4849 */
    4950int ext4_filesystem_init(ext4_filesystem_t *fs, service_id_t service_id,
    50                 enum cache_mode cmode)
    51 {
    52         int rc;
    53 
     51    enum cache_mode cmode)
     52{
    5453        fs->device = service_id;
    55 
     54       
    5655        /* Initialize block library (4096 is size of communication channel) */
    57         rc = block_init(EXCHANGE_SERIALIZE, fs->device, 4096);
    58         if (rc != EOK) {
     56        int rc = block_init(EXCHANGE_SERIALIZE, fs->device, 4096);
     57        if (rc != EOK)
    5958                return rc;
    60         }
    61 
     59       
    6260        /* Read superblock from device to memory */
    6361        ext4_superblock_t *temp_superblock;
     
    6765                return rc;
    6866        }
    69 
     67       
    7068        /* Read block size from superblock and check */
    7169        uint32_t block_size = ext4_superblock_get_block_size(temp_superblock);
     
    7472                return ENOTSUP;
    7573        }
    76 
     74       
    7775        /* Initialize block caching by libblock */
    7876        rc = block_cache_init(service_id, block_size, 0, cmode);
     
    8179                return rc;
    8280        }
    83 
     81       
    8482        /* Compute limits for indirect block levels */
    8583        uint32_t block_ids_per_block = block_size / sizeof(uint32_t);
    8684        fs->inode_block_limits[0] = EXT4_INODE_DIRECT_BLOCK_COUNT;
    8785        fs->inode_blocks_per_level[0] = 1;
    88         for (int i = 1; i < 4; i++) {
    89                 fs->inode_blocks_per_level[i] = fs->inode_blocks_per_level[i-1] *
     86        for (unsigned int i = 1; i < 4; i++) {
     87                fs->inode_blocks_per_level[i] = fs->inode_blocks_per_level[i - 1] *
    9088                    block_ids_per_block;
    91                 fs->inode_block_limits[i] = fs->inode_block_limits[i-1] +
    92                                 fs->inode_blocks_per_level[i];
    93         }
    94 
     89                fs->inode_block_limits[i] = fs->inode_block_limits[i - 1] +
     90                    fs->inode_blocks_per_level[i];
     91        }
     92       
    9593        /* Return loaded superblock */
    9694        fs->superblock = temp_superblock;
    97 
     95       
    9896        uint16_t state = ext4_superblock_get_state(fs->superblock);
    99 
     97       
    10098        if (state != EXT4_SUPERBLOCK_STATE_VALID_FS) {
    10199                block_cache_fini(fs->device);
     
    103101                return ENOTSUP;
    104102        }
    105 
     103       
    106104        /* Mark system as mounted */
    107105        ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_ERROR_FS);
     
    112110                return rc;
    113111        }
    114 
     112       
    115113        uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock);
    116114        ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1);
    117 
     115       
    118116        return EOK;
    119117}
     
    121119/** Destroy filesystem instance (used by unmount operation).
    122120 *
    123  * @param fs            filesystem to be destroyed
    124  * @param write_sb      flag if superblock should be written to device
    125  * @return                      error code
     121 * @param fs Filesystem to be destroyed
     122 *
     123 * @return Error code
     124 *
    126125 */
    127126int ext4_filesystem_fini(ext4_filesystem_t *fs)
    128127{
    129         int rc = EOK;
    130 
    131128        /* Write the superblock to the device */
    132129        ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_VALID_FS);
    133         rc = ext4_superblock_write_direct(fs->device, fs->superblock);
    134 
     130        int rc = ext4_superblock_write_direct(fs->device, fs->superblock);
     131       
    135132        /* Release memory space for superblock */
    136133        free(fs->superblock);
    137 
     134       
    138135        /* Finish work with block library */
    139136        block_cache_fini(fs->device);
    140137        block_fini(fs->device);
    141 
     138       
    142139        return rc;
    143140}
     
    147144 * Main is the check of the superblock structure.
    148145 *
    149  * @param fs            filesystem to be checked
    150  * @return                      error code
     146 * @param fs Filesystem to be checked
     147 *
     148 * @return Error code
     149 *
    151150 */
    152151int ext4_filesystem_check_sanity(ext4_filesystem_t *fs)
    153152{
    154         int rc;
    155 
    156153        /* Check superblock */
    157         rc = ext4_superblock_check_sanity(fs->superblock);
    158         if (rc != EOK) {
    159                 return rc;
    160         }
    161 
    162         return EOK;
     154        return ext4_superblock_check_sanity(fs->superblock);
    163155}
    164156
     
    169161 * during some write operations.
    170162 *
    171  * @param fs                    filesystem to be checked
    172  * @param read_only             flag if filesystem should be mounted only for reading
    173  * @return                              error code
     163 * @param fs        Filesystem to be checked
     164 * @param read_only Flag if filesystem should be mounted only for reading
     165 *
     166 * @return Error code
     167 *
    174168 */
    175169int ext4_filesystem_check_features(ext4_filesystem_t *fs, bool *read_only)
     
    180174                return EOK;
    181175        }
    182 
    183         /* Check incompatible features - if filesystem has some,
     176       
     177        /*
     178         * Check incompatible features - if filesystem has some,
    184179         * volume can't be mounted
    185180         */
    186181        uint32_t incompatible_features;
    187         incompatible_features = ext4_superblock_get_features_incompatible(fs->superblock);
     182        incompatible_features =
     183            ext4_superblock_get_features_incompatible(fs->superblock);
    188184        incompatible_features &= ~EXT4_FEATURE_INCOMPAT_SUPP;
    189         if (incompatible_features > 0) {
     185        if (incompatible_features > 0)
    190186                return ENOTSUP;
    191         }
    192 
    193         /* Check read-only features, if filesystem has some,
     187       
     188        /*
     189         * Check read-only features, if filesystem has some,
    194190         * volume can be mount only in read-only mode
    195191         */
    196192        uint32_t compatible_read_only;
    197         compatible_read_only = ext4_superblock_get_features_read_only(fs->superblock);
     193        compatible_read_only =
     194            ext4_superblock_get_features_read_only(fs->superblock);
    198195        compatible_read_only &= ~EXT4_FEATURE_RO_COMPAT_SUPP;
    199196        if (compatible_read_only > 0) {
     
    201198                return EOK;
    202199        }
    203 
     200       
    204201        return EOK;
    205202}
     
    208205/** Convert block address to relative index in block group.
    209206 *
    210  * @param sb                    superblock pointer
    211  * @param block_addr    block number to convert
    212  * @return                              relative number of block
     207 * @param sb         Superblock pointer
     208 * @param block_addr Block number to convert
     209 *
     210 * @return Relative number of block
     211 *
    213212 */
    214213uint32_t ext4_filesystem_blockaddr2_index_in_group(ext4_superblock_t *sb,
    215                 uint32_t block_addr)
     214    uint32_t block_addr)
    216215{
    217216        uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
    218217        uint32_t first_block = ext4_superblock_get_first_data_block(sb);
    219 
     218       
    220219        /* First block == 0 or 1 */
    221         if (first_block == 0) {
     220        if (first_block == 0)
    222221                return block_addr % blocks_per_group;
    223         } else {
     222        else
    224223                return (block_addr - 1) % blocks_per_group;
    225         }
    226224}
    227225
     
    229227/** Convert relative block address in group to absolute address.
    230228 *
    231  * @param sb                    superblock pointer
    232  * @param block_addr    block number to convert
    233  * @return                              absolute block address
     229 * @param sb Superblock pointer
     230 *
     231 * @return Absolute block address
     232 *
    234233 */
    235234uint32_t ext4_filesystem_index_in_group2blockaddr(ext4_superblock_t *sb,
    236                 uint32_t index, uint32_t bgid)
     235    uint32_t index, uint32_t bgid)
    237236{
    238237        uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
    239 
    240         if (ext4_superblock_get_first_data_block(sb) == 0) {
     238       
     239        if (ext4_superblock_get_first_data_block(sb) == 0)
    241240                return bgid * blocks_per_group + index;
    242         } else {
     241        else
    243242                return bgid * blocks_per_group + index + 1;
    244         }
    245 
    246243}
    247244
    248245/** Initialize block bitmap in block group.
    249  *
    250  * @param bg_ref        reference to block group
    251  * @return                      error code
     246 *
     247 * @param bg_ref Reference to block group
     248 *
     249 * @return Error code
     250 *
    252251 */
    253252static int ext4_filesystem_init_block_bitmap(ext4_block_group_ref_t *bg_ref)
    254253{
    255         int rc;
    256 
    257254        /* Load bitmap */
    258255        uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
    259                         bg_ref->block_group, bg_ref->fs->superblock);
     256            bg_ref->block_group, bg_ref->fs->superblock);
     257       
    260258        block_t *bitmap_block;
    261 
    262         rc = block_get(&bitmap_block, bg_ref->fs->device,
    263                         bitmap_block_addr, BLOCK_FLAGS_NOREAD);
    264         if (rc != EOK) {
     259        int rc = block_get(&bitmap_block, bg_ref->fs->device,
     260            bitmap_block_addr, BLOCK_FLAGS_NOREAD);
     261        if (rc != EOK)
    265262                return rc;
    266         }
    267 
     263       
    268264        uint8_t *bitmap = bitmap_block->data;
    269 
     265       
    270266        /* Initialize all bitmap bits to zero */
    271267        uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock);
    272268        memset(bitmap, 0, block_size);
    273 
     269       
    274270        /* Determine first block and first data block in group */
    275271        uint32_t first_idx = 0;
    276 
     272       
    277273        uint32_t first_data = ext4_balloc_get_first_data_block_in_group(
    278                         bg_ref->fs->superblock, bg_ref);
     274            bg_ref->fs->superblock, bg_ref);
    279275        uint32_t first_data_idx = ext4_filesystem_blockaddr2_index_in_group(
    280                         bg_ref->fs->superblock, first_data);
    281 
     276            bg_ref->fs->superblock, first_data);
     277       
    282278        /* Set bits from to first block to first data block - 1 to one (allocated) */
    283         for (uint32_t block = first_idx; block < first_data_idx; ++block) {
     279        for (uint32_t block = first_idx; block < first_data_idx; ++block)
    284280                ext4_bitmap_set_bit(bitmap, block);
    285         }
    286 
     281       
    287282        bitmap_block->dirty = true;
    288 
     283       
    289284        /* Save bitmap */
    290         rc = block_put(bitmap_block);
    291         if (rc != EOK) {
    292                 return rc;
    293         }
    294 
    295         return EOK;
     285        return block_put(bitmap_block);
    296286}
    297287
    298288/** Initialize i-node bitmap in block group.
    299  *
    300  * @param bg_ref        reference to block group
    301  * @return                      error code
     289 *
     290 * @param bg_ref Reference to block group
     291 *
     292 * @return Error code
     293 *
    302294 */
    303295static int ext4_filesystem_init_inode_bitmap(ext4_block_group_ref_t *bg_ref)
    304296{
    305         int rc;
    306 
    307297        /* Load bitmap */
    308298        uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
    309                         bg_ref->block_group, bg_ref->fs->superblock);
     299            bg_ref->block_group, bg_ref->fs->superblock);
    310300        block_t *bitmap_block;
    311 
    312         rc = block_get(&bitmap_block, bg_ref->fs->device,
    313                         bitmap_block_addr, BLOCK_FLAGS_NOREAD);
    314         if (rc != EOK) {
     301       
     302        int rc = block_get(&bitmap_block, bg_ref->fs->device,
     303            bitmap_block_addr, BLOCK_FLAGS_NOREAD);
     304        if (rc != EOK)
    315305                return rc;
    316         }
    317 
     306       
    318307        uint8_t *bitmap = bitmap_block->data;
    319 
     308       
    320309        /* Initialize all bitmap bits to zero */
    321310        uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock);
    322311        uint32_t inodes_per_group =
    323                         ext4_superblock_get_inodes_per_group(bg_ref->fs->superblock);
     312            ext4_superblock_get_inodes_per_group(bg_ref->fs->superblock);
    324313        memset(bitmap, 0, (inodes_per_group + 7) / 8);
    325 
     314       
    326315        uint32_t start_bit = inodes_per_group;
    327316        uint32_t end_bit = block_size * 8;
    328 
     317       
    329318        uint32_t i;
    330         for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++) {
     319        for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
    331320                ext4_bitmap_set_bit(bitmap, i);
    332         }
    333 
    334         if (i < end_bit) {
     321       
     322        if (i < end_bit)
    335323                memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
    336         }
    337 
     324       
    338325        bitmap_block->dirty = true;
    339 
     326       
    340327        /* Save bitmap */
    341         rc = block_put(bitmap_block);
    342         if (rc != EOK) {
    343                 return rc;
    344         }
    345 
    346         return EOK;
     328        return block_put(bitmap_block);
    347329}
    348330
    349331/** Initialize i-node table in block group.
    350  *
    351  * @param bg_ref        reference to block group
    352  * @return                      error code
     332 *
     333 * @param bg_ref Reference to block group
     334 *
     335 * @return Error code
     336 *
    353337 */
    354338static int ext4_filesystem_init_inode_table(ext4_block_group_ref_t *bg_ref)
    355339{
    356         int rc;
    357 
    358340        ext4_superblock_t *sb = bg_ref->fs->superblock;
    359 
     341       
    360342        uint32_t inode_size = ext4_superblock_get_inode_size(sb);
    361343        uint32_t block_size = ext4_superblock_get_block_size(sb);
    362344        uint32_t inodes_per_block = block_size / inode_size;
    363 
     345       
    364346        uint32_t inodes_in_group =
    365                         ext4_superblock_get_inodes_in_group(sb, bg_ref->index);
    366 
     347            ext4_superblock_get_inodes_in_group(sb, bg_ref->index);
     348       
    367349        uint32_t table_blocks = inodes_in_group / inodes_per_block;
    368 
    369         if (inodes_in_group % inodes_per_block) {
     350       
     351        if (inodes_in_group % inodes_per_block)
    370352                table_blocks++;
    371         }
    372 
     353       
    373354        /* Compute initialization bounds */
    374355        uint32_t first_block = ext4_block_group_get_inode_table_first_block(
    375                         bg_ref->block_group, sb);
    376 
     356            bg_ref->block_group, sb);
     357       
    377358        uint32_t last_block = first_block + table_blocks - 1;
    378 
     359       
    379360        /* Initialization of all itable blocks */
    380361        for (uint32_t fblock = first_block; fblock <= last_block; ++fblock) {
    381362                block_t *block;
    382                 rc = block_get(&block, bg_ref->fs->device, fblock, BLOCK_FLAGS_NOREAD);
    383                 if (rc != EOK) {
    384                         return rc;
    385                 }
    386 
     363                int rc = block_get(&block, bg_ref->fs->device, fblock,
     364                    BLOCK_FLAGS_NOREAD);
     365                if (rc != EOK)
     366                        return rc;
     367               
    387368                memset(block->data, 0, block_size);
    388369                block->dirty = true;
    389 
     370               
    390371                rc = block_put(block);
    391                 if (rc != EOK) {
    392                         return rc;
    393                 }
    394         }
    395 
     372                if (rc != EOK)
     373                        return rc;
     374        }
     375       
    396376        return EOK;
    397377}
     
    399379/** Get reference to block group specified by index.
    400380 *
    401  * @param fs            filesystem to find block group on
    402  * @param bgid          index of block group to load
    403  * @param ref           output pointer for reference
    404  * @return                      error code
     381 * @param fs   Filesystem to find block group on
     382 * @param bgid Index of block group to load
     383 * @param ref  Output pointer for reference
     384 *
     385 * @return Error code
     386 *
    405387 */
    406388int ext4_filesystem_get_block_group_ref(ext4_filesystem_t *fs, uint32_t bgid,
    407389    ext4_block_group_ref_t **ref)
    408390{
    409         int rc;
    410 
    411391        /* Allocate memory for new structure */
    412         ext4_block_group_ref_t *newref = malloc(sizeof(ext4_block_group_ref_t));
    413         if (newref == NULL) {
     392        ext4_block_group_ref_t *newref =
     393            malloc(sizeof(ext4_block_group_ref_t));
     394        if (newref == NULL)
    414395                return ENOMEM;
    415         }
    416 
     396       
    417397        /* Compute number of descriptors, that fits in one data block */
    418         uint32_t descriptors_per_block = ext4_superblock_get_block_size(fs->superblock)
    419             / ext4_superblock_get_desc_size(fs->superblock);
    420 
     398        uint32_t descriptors_per_block =
     399            ext4_superblock_get_block_size(fs->superblock) /
     400            ext4_superblock_get_desc_size(fs->superblock);
     401       
    421402        /* Block group descriptor table starts at the next block after superblock */
    422         aoff64_t block_id = ext4_superblock_get_first_data_block(fs->superblock) + 1;
    423 
     403        aoff64_t block_id =
     404            ext4_superblock_get_first_data_block(fs->superblock) + 1;
     405       
    424406        /* Find the block containing the descriptor we are looking for */
    425407        block_id += bgid / descriptors_per_block;
    426         uint32_t offset = (bgid % descriptors_per_block) * ext4_superblock_get_desc_size(fs->superblock);
    427 
     408        uint32_t offset = (bgid % descriptors_per_block) *
     409            ext4_superblock_get_desc_size(fs->superblock);
     410       
    428411        /* Load block with descriptors */
    429         rc = block_get(&newref->block, fs->device, block_id, 0);
     412        int rc = block_get(&newref->block, fs->device, block_id, 0);
    430413        if (rc != EOK) {
    431414                free(newref);
    432415                return rc;
    433416        }
    434 
     417       
    435418        /* Inititialize in-memory representation */
    436419        newref->block_group = newref->block->data + offset;
     
    438421        newref->index = bgid;
    439422        newref->dirty = false;
    440 
     423       
    441424        *ref = newref;
    442 
     425       
    443426        if (ext4_block_group_has_flag(newref->block_group,
    444                         EXT4_BLOCK_GROUP_BLOCK_UNINIT)) {
    445 
     427            EXT4_BLOCK_GROUP_BLOCK_UNINIT)) {
    446428                rc = ext4_filesystem_init_block_bitmap(newref);
    447429                if (rc != EOK) {
     
    450432                        return rc;
    451433                }
     434               
    452435                ext4_block_group_clear_flag(newref->block_group,
    453                                 EXT4_BLOCK_GROUP_BLOCK_UNINIT);
    454 
     436                    EXT4_BLOCK_GROUP_BLOCK_UNINIT);
     437               
    455438                newref->dirty = true;
    456439        }
    457 
     440       
    458441        if (ext4_block_group_has_flag(newref->block_group,
    459                         EXT4_BLOCK_GROUP_INODE_UNINIT)) {
    460 
     442            EXT4_BLOCK_GROUP_INODE_UNINIT)) {
    461443                rc = ext4_filesystem_init_inode_bitmap(newref);
    462444                if (rc != EOK) {
     
    465447                        return rc;
    466448                }
    467 
     449               
    468450                ext4_block_group_clear_flag(newref->block_group,
    469                                 EXT4_BLOCK_GROUP_INODE_UNINIT);
    470 
    471                 if (! ext4_block_group_has_flag(newref->block_group,
    472                                 EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
    473 
     451                    EXT4_BLOCK_GROUP_INODE_UNINIT);
     452               
     453                if (!ext4_block_group_has_flag(newref->block_group,
     454                    EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
    474455                        rc = ext4_filesystem_init_inode_table(newref);
    475                         if (rc != EOK) {
     456                        if (rc != EOK)
    476457                                return rc;
    477                         }
    478 
     458                       
    479459                        ext4_block_group_set_flag(newref->block_group,
    480                                         EXT4_BLOCK_GROUP_ITABLE_ZEROED);
    481 
     460                            EXT4_BLOCK_GROUP_ITABLE_ZEROED);
    482461                }
     462               
    483463                newref->dirty = true;
    484 
    485         }
    486 
     464        }
     465       
    487466        return EOK;
    488467}
     
    492471 * It uses crc functions from Linux kernel implementation.
    493472 *
    494  * @param sb            superblock
    495  * @param bgid          index of block group in the filesystem
    496  * @param bg            block group to compute checksum for
    497  * @return                      checksum value
     473 * @param sb   Superblock
     474 * @param bgid Index of block group in the filesystem
     475 * @param bg   Block group to compute checksum for
     476 *
     477 * @return Checksum value
     478 *
    498479 */
    499480static uint16_t ext4_filesystem_bg_checksum(ext4_superblock_t *sb, uint32_t bgid,
    500                             ext4_block_group_t *bg)
     481    ext4_block_group_t *bg)
    501482{
    502483        /* If checksum not supported, 0 will be returned */
    503484        uint16_t crc = 0;
    504 
     485       
    505486        /* Compute the checksum only if the filesystem supports it */
    506         if (ext4_superblock_has_feature_read_only(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
    507 
     487        if (ext4_superblock_has_feature_read_only(sb,
     488            EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
    508489                void *base = bg;
    509490                void *checksum = &bg->checksum;
    510 
    511                 uint32_t offset = (uint32_t)(checksum - base);
    512 
     491               
     492                uint32_t offset = (uint32_t) (checksum - base);
     493               
    513494                /* Convert block group index to little endian */
    514495                uint32_t le_group = host2uint32_t_le(bgid);
    515 
     496               
    516497                /* Initialization */
    517498                crc = crc16(~0, sb->uuid, sizeof(sb->uuid));
    518 
     499               
    519500                /* Include index of block group */
    520                 crc = crc16(crc, (uint8_t *)&le_group, sizeof(le_group));
    521 
     501                crc = crc16(crc, (uint8_t *) &le_group, sizeof(le_group));
     502               
    522503                /* Compute crc from the first part (stop before checksum field) */
    523                 crc = crc16(crc, (uint8_t *)bg, offset);
    524 
     504                crc = crc16(crc, (uint8_t *) bg, offset);
     505               
    525506                /* Skip checksum */
    526507                offset += sizeof(bg->checksum);
    527 
     508               
    528509                /* Checksum of the rest of block group descriptor */
    529                 if ((ext4_superblock_has_feature_incompatible(sb, EXT4_FEATURE_INCOMPAT_64BIT)) &&
    530                         offset < ext4_superblock_get_desc_size(sb)) {
    531 
    532                         crc = crc16(crc, ((uint8_t *)bg) + offset, ext4_superblock_get_desc_size(sb) - offset);
    533                 }
    534         }
    535 
     510                if ((ext4_superblock_has_feature_incompatible(sb,
     511                    EXT4_FEATURE_INCOMPAT_64BIT)) &&
     512                    (offset < ext4_superblock_get_desc_size(sb)))
     513                        crc = crc16(crc, ((uint8_t *) bg) + offset,
     514                            ext4_superblock_get_desc_size(sb) - offset);
     515        }
     516       
    536517        return crc;
    537 
    538518}
    539519
    540520/** Put reference to block group.
    541521 *
    542  * @oaram ref           pointer for reference to be put back
    543  * @return                      error code
     522 * @oaram ref Pointer for reference to be put back
     523 *
     524 * @return Error code
     525 *
    544526 */
    545527int ext4_filesystem_put_block_group_ref(ext4_block_group_ref_t *ref)
    546528{
    547         int rc;
    548 
    549529        /* Check if reference modified */
    550530        if (ref->dirty) {
    551 
    552531                /* Compute new checksum of block group */
    553                 uint16_t checksum = ext4_filesystem_bg_checksum(
    554                                 ref->fs->superblock, ref->index, ref->block_group);
     532                uint16_t checksum =
     533                    ext4_filesystem_bg_checksum(ref->fs->superblock, ref->index,
     534                    ref->block_group);
    555535                ext4_block_group_set_checksum(ref->block_group, checksum);
    556 
     536               
    557537                /* Mark block dirty for writing changes to physical device */
    558538                ref->block->dirty = true;
    559539        }
    560 
     540       
    561541        /* Put back block, that contains block group descriptor */
    562         rc = block_put(ref->block);
     542        int rc = block_put(ref->block);
    563543        free(ref);
    564 
     544       
    565545        return rc;
    566546}
     
    568548/** Get reference to i-node specified by index.
    569549 *
    570  * @param fs            filesystem to find i-node on
    571  * @param index         index of i-node to load
    572  * @oaram ref           output pointer for reference
    573  * @return                      error code
     550 * @param fs    Filesystem to find i-node on
     551 * @param index Index of i-node to load
     552 * @oaram ref   Output pointer for reference
     553 *
     554 * @return Error code
     555 *
    574556 */
    575557int ext4_filesystem_get_inode_ref(ext4_filesystem_t *fs, uint32_t index,
    576558    ext4_inode_ref_t **ref)
    577559{
    578         int rc;
    579 
    580560        /* Allocate memory for new structure */
    581         ext4_inode_ref_t *newref = malloc(sizeof(ext4_inode_ref_t));
    582         if (newref == NULL) {
     561        ext4_inode_ref_t *newref =
     562            malloc(sizeof(ext4_inode_ref_t));
     563        if (newref == NULL)
    583564                return ENOMEM;
    584         }
    585 
     565       
    586566        /* Compute number of i-nodes, that fits in one data block */
    587567        uint32_t inodes_per_group =
    588                         ext4_superblock_get_inodes_per_group(fs->superblock);
    589 
    590         /* Inode numbers are 1-based, but it is simpler to work with 0-based
     568            ext4_superblock_get_inodes_per_group(fs->superblock);
     569       
     570        /*
     571         * Inode numbers are 1-based, but it is simpler to work with 0-based
    591572         * when computing indices
    592573         */
     
    594575        uint32_t block_group = index / inodes_per_group;
    595576        uint32_t offset_in_group = index % inodes_per_group;
    596 
     577       
    597578        /* Load block group, where i-node is located */
    598579        ext4_block_group_ref_t *bg_ref;
    599         rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
     580        int rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
    600581        if (rc != EOK) {
    601582                free(newref);
    602583                return rc;
    603584        }
    604 
     585       
    605586        /* Load block address, where i-node table is located */
    606         uint32_t inode_table_start = ext4_block_group_get_inode_table_first_block(
    607             bg_ref->block_group, fs->superblock);
    608 
     587        uint32_t inode_table_start =
     588            ext4_block_group_get_inode_table_first_block(bg_ref->block_group,
     589            fs->superblock);
     590       
    609591        /* Put back block group reference (not needed more) */
    610592        rc = ext4_filesystem_put_block_group_ref(bg_ref);
     
    613595                return rc;
    614596        }
    615 
     597       
    616598        /* Compute position of i-node in the block group */
    617599        uint16_t inode_size = ext4_superblock_get_inode_size(fs->superblock);
    618600        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    619601        uint32_t byte_offset_in_group = offset_in_group * inode_size;
    620 
     602       
    621603        /* Compute block address */
    622604        aoff64_t block_id = inode_table_start + (byte_offset_in_group / block_size);
     
    626608                return rc;
    627609        }
    628 
     610       
    629611        /* Compute position of i-node in the data block */
    630612        uint32_t offset_in_block = byte_offset_in_group % block_size;
    631613        newref->inode = newref->block->data + offset_in_block;
    632 
     614       
    633615        /* We need to store the original value of index in the reference */
    634616        newref->index = index + 1;
    635617        newref->fs = fs;
    636618        newref->dirty = false;
    637 
     619       
    638620        *ref = newref;
    639 
     621       
    640622        return EOK;
    641623}
     
    643625/** Put reference to i-node.
    644626 *
    645  * @param ref           pointer for reference to be put back
    646  * @return                      error code
     627 * @param ref Pointer for reference to be put back
     628 *
     629 * @return Error code
     630 *
    647631 */
    648632int ext4_filesystem_put_inode_ref(ext4_inode_ref_t *ref)
    649633{
    650         int rc;
    651 
    652634        /* Check if reference modified */
    653635        if (ref->dirty) {
    654 
    655636                /* Mark block dirty for writing changes to physical device */
    656637                ref->block->dirty = true;
    657638        }
    658 
     639       
    659640        /* Put back block, that contains i-node */
    660         rc = block_put(ref->block);
     641        int rc = block_put(ref->block);
    661642        free(ref);
    662 
     643       
    663644        return rc;
    664645}
     
    666647/** Allocate new i-node in the filesystem.
    667648 *
    668  * @param fs                    filesystem to allocated i-node on
    669  * @param inode_ref             output pointer to return reference to allocated i-node
    670  * @param flags                 flags to be set for newly created i-node
    671  * @return                              error code
     649 * @param fs        Filesystem to allocated i-node on
     650 * @param inode_ref Output pointer to return reference to allocated i-node
     651 * @param flags     Flags to be set for newly created i-node
     652 *
     653 * @return Error code
     654 *
    672655 */
    673656int ext4_filesystem_alloc_inode(ext4_filesystem_t *fs,
    674                 ext4_inode_ref_t **inode_ref, int flags)
    675 {
    676         int rc;
    677 
     657    ext4_inode_ref_t **inode_ref, int flags)
     658{
    678659        /* Check if newly allocated i-node will be a directory */
    679660        bool is_dir = false;
    680         if (flags & L_DIRECTORY) {
     661        if (flags & L_DIRECTORY)
    681662                is_dir = true;
    682         }
    683 
     663       
    684664        /* Allocate inode by allocation algorithm */
    685665        uint32_t index;
    686         rc = ext4_ialloc_alloc_inode(fs, &index, is_dir);
    687         if (rc != EOK) {
     666        int rc = ext4_ialloc_alloc_inode(fs, &index, is_dir);
     667        if (rc != EOK)
    688668                return rc;
    689         }
    690 
     669       
    691670        /* Load i-node from on-disk i-node table */
    692671        rc = ext4_filesystem_get_inode_ref(fs, index, inode_ref);
     
    695674                return rc;
    696675        }
    697 
     676       
    698677        /* Initialize i-node */
    699678        ext4_inode_t *inode = (*inode_ref)->inode;
    700 
     679       
    701680        uint16_t mode;
    702681        if (is_dir) {
     
    705684                 * 0777 (octal) == rwxrwxrwx
    706685                 */
     686               
    707687                mode = 0777;
    708688                mode |= EXT4_INODE_MODE_DIRECTORY;
    709689                ext4_inode_set_mode(fs->superblock, inode, mode);
    710                 ext4_inode_set_links_count(inode, 1); /* '.' entry */
     690                ext4_inode_set_links_count(inode, 1);  /* '.' entry */
    711691        } else {
    712692                /*
     
    714694                 * 0666 (octal) == rw-rw-rw-
    715695                 */
    716 
     696               
    717697                mode = 0666;
    718698                mode |= EXT4_INODE_MODE_FILE;
     
    720700                ext4_inode_set_links_count(inode, 0);
    721701        }
    722 
     702       
    723703        ext4_inode_set_uid(inode, 0);
    724704        ext4_inode_set_gid(inode, 0);
     
    731711        ext4_inode_set_flags(inode, 0);
    732712        ext4_inode_set_generation(inode, 0);
    733 
     713       
    734714        /* Reset blocks array */
    735         for (uint32_t i = 0; i < EXT4_INODE_BLOCKS; i++) {
     715        for (uint32_t i = 0; i < EXT4_INODE_BLOCKS; i++)
    736716                inode->blocks[i] = 0;
    737         }
    738 
     717       
    739718        /* Initialize extents if needed */
    740719        if (ext4_superblock_has_feature_incompatible(
    741                         fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
    742 
     720            fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
    743721                ext4_inode_set_flag(inode, EXT4_INODE_FLAG_EXTENTS);
    744 
     722               
    745723                /* Initialize extent root header */
    746724                ext4_extent_header_t *header = ext4_inode_get_extent_header(inode);
     
    749727                ext4_extent_header_set_generation(header, 0);
    750728                ext4_extent_header_set_magic(header, EXT4_EXTENT_MAGIC);
    751 
    752                 uint16_t max_entries = (EXT4_INODE_BLOCKS * sizeof (uint32_t) - sizeof(ext4_extent_header_t))
    753                                 / sizeof(ext4_extent_t);
    754 
     729               
     730                uint16_t max_entries = (EXT4_INODE_BLOCKS * sizeof(uint32_t) -
     731                    sizeof(ext4_extent_header_t)) / sizeof(ext4_extent_t);
     732               
    755733                ext4_extent_header_set_max_entries_count(header, max_entries);
    756734        }
    757 
     735       
    758736        (*inode_ref)->dirty = true;
    759 
     737       
    760738        return EOK;
    761739}
     
    763741/** Release i-node and mark it as free.
    764742 *
    765  * @param inode_ref                     i-node to be released
    766  * @return                                      error code
     743 * @param inode_ref I-node to be released
     744 *
     745 * @return Error code
     746 *
    767747 */
    768748int ext4_filesystem_free_inode(ext4_inode_ref_t *inode_ref)
    769749{
    770         int rc;
    771 
    772750        ext4_filesystem_t *fs = inode_ref->fs;
    773 
     751       
    774752        /* For extents must be data block destroyed by other way */
    775         if (ext4_superblock_has_feature_incompatible(
    776                         fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    777                                 ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
    778 
     753        if ((ext4_superblock_has_feature_incompatible(fs->superblock,
     754            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     755            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
    779756                /* Data structures are released during truncate operation... */
    780757                goto finish;
    781758        }
    782 
     759       
    783760        /* Release all indirect (no data) blocks */
    784 
     761       
    785762        /* 1) Single indirect */
    786763        uint32_t fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0);
    787764        if (fblock != 0) {
    788                 rc = ext4_balloc_free_block(inode_ref, fblock);
    789                 if (rc != EOK) {
    790                         return rc;
    791                 }
    792 
     765                int rc = ext4_balloc_free_block(inode_ref, fblock);
     766                if (rc != EOK)
     767                        return rc;
     768               
    793769                ext4_inode_set_indirect_block(inode_ref->inode, 0, 0);
    794770        }
    795 
     771       
    796772        block_t *block;
    797773        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    798774        uint32_t count = block_size / sizeof(uint32_t);
    799 
     775       
    800776        /* 2) Double indirect */
    801777        fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1);
    802778        if (fblock != 0) {
    803                 rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
    804                 if (rc != EOK) {
    805                         return rc;
    806                 }
    807 
     779                int rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
     780                if (rc != EOK)
     781                        return rc;
     782               
    808783                uint32_t ind_block;
    809784                for (uint32_t offset = 0; offset < count; ++offset) {
    810                         ind_block = uint32_t_le2host(((uint32_t*)block->data)[offset]);
    811 
     785                        ind_block = uint32_t_le2host(((uint32_t *) block->data)[offset]);
     786                       
    812787                        if (ind_block != 0) {
    813788                                rc = ext4_balloc_free_block(inode_ref, ind_block);
     
    818793                        }
    819794                }
    820 
     795               
    821796                block_put(block);
    822797                rc = ext4_balloc_free_block(inode_ref, fblock);
    823                 if (rc != EOK) {
    824                         return rc;
    825                 }
    826 
     798                if (rc != EOK)
     799                        return rc;
     800               
    827801                ext4_inode_set_indirect_block(inode_ref->inode, 1, 0);
    828802        }
    829 
    830 
     803       
    831804        /* 3) Tripple indirect */
    832805        block_t *subblock;
    833806        fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2);
    834807        if (fblock != 0) {
    835                 rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
    836                 if (rc != EOK) {
    837                         return rc;
    838                 }
    839 
     808                int rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
     809                if (rc != EOK)
     810                        return rc;
     811               
    840812                uint32_t ind_block;
    841813                for (uint32_t offset = 0; offset < count; ++offset) {
    842                         ind_block = uint32_t_le2host(((uint32_t*)block->data)[offset]);
    843 
     814                        ind_block = uint32_t_le2host(((uint32_t *) block->data)[offset]);
     815                       
    844816                        if (ind_block != 0) {
    845                                 rc = block_get(&subblock, fs->device, ind_block, BLOCK_FLAGS_NONE);
     817                                rc = block_get(&subblock, fs->device, ind_block,
     818                                    BLOCK_FLAGS_NONE);
    846819                                if (rc != EOK) {
    847820                                        block_put(block);
    848821                                        return rc;
    849822                                }
    850 
     823                               
    851824                                uint32_t ind_subblock;
    852                                 for (uint32_t suboffset = 0; suboffset < count; ++suboffset) {
    853                                         ind_subblock = uint32_t_le2host(((uint32_t*)subblock->data)[suboffset]);
    854 
     825                                for (uint32_t suboffset = 0; suboffset < count;
     826                                    ++suboffset) {
     827                                        ind_subblock = uint32_t_le2host(((uint32_t *)
     828                                            subblock->data)[suboffset]);
     829                                       
    855830                                        if (ind_subblock != 0) {
    856831                                                rc = ext4_balloc_free_block(inode_ref, ind_subblock);
     
    861836                                                }
    862837                                        }
    863 
    864838                                }
     839                               
    865840                                block_put(subblock);
    866 
    867841                        }
    868 
     842                       
    869843                        rc = ext4_balloc_free_block(inode_ref, ind_block);
    870844                        if (rc != EOK) {
     
    872846                                return rc;
    873847                        }
    874 
    875 
    876848                }
    877 
     849               
    878850                block_put(block);
    879851                rc = ext4_balloc_free_block(inode_ref, fblock);
    880                 if (rc != EOK) {
    881                         return rc;
    882                 }
    883 
     852                if (rc != EOK)
     853                        return rc;
     854               
    884855                ext4_inode_set_indirect_block(inode_ref->inode, 2, 0);
    885856        }
    886 
     857       
    887858finish:
    888 
    889859        /* Mark inode dirty for writing to the physical device */
    890860        inode_ref->dirty = true;
    891 
     861       
    892862        /* Free block with extended attributes if present */
    893863        uint32_t xattr_block = ext4_inode_get_file_acl(
    894                         inode_ref->inode, fs->superblock);
     864            inode_ref->inode, fs->superblock);
    895865        if (xattr_block) {
    896                 rc = ext4_balloc_free_block(inode_ref, xattr_block);
    897                 if (rc != EOK) {
    898                         return rc;
    899                 }
    900 
     866                int rc = ext4_balloc_free_block(inode_ref, xattr_block);
     867                if (rc != EOK)
     868                        return rc;
     869               
    901870                ext4_inode_set_file_acl(inode_ref->inode, fs->superblock, 0);
    902871        }
    903 
     872       
    904873        /* Free inode by allocator */
     874        int rc;
    905875        if (ext4_inode_is_type(fs->superblock, inode_ref->inode,
    906                         EXT4_INODE_MODE_DIRECTORY)) {
     876            EXT4_INODE_MODE_DIRECTORY))
    907877                rc = ext4_ialloc_free_inode(fs, inode_ref->index, true);
    908         } else {
     878        else
    909879                rc = ext4_ialloc_free_inode(fs, inode_ref->index, false);
    910         }
    911         if (rc != EOK) {
    912                 return rc;
    913         }
    914 
    915         return EOK;
     880       
     881        return rc;
    916882}
    917883
    918884/** Truncate i-node data blocks.
    919885 *
    920  * @param inode_ref             i-node to be truncated
    921  * @param new_size              new size of inode (must be < current size)
    922  * @return                              error code
    923  */
    924 int ext4_filesystem_truncate_inode(
    925                 ext4_inode_ref_t *inode_ref, aoff64_t new_size)
    926 {
    927         int rc;
    928 
     886 * @param inode_ref I-node to be truncated
     887 * @param new_size  New size of inode (must be < current size)
     888 *
     889 * @return Error code
     890 *
     891 */
     892int ext4_filesystem_truncate_inode(ext4_inode_ref_t *inode_ref,
     893    aoff64_t new_size)
     894{
    929895        ext4_superblock_t *sb = inode_ref->fs->superblock;
    930 
     896       
    931897        /* Check flags, if i-node can be truncated */
    932         if (! ext4_inode_can_truncate(sb, inode_ref->inode)) {
     898        if (!ext4_inode_can_truncate(sb, inode_ref->inode))
    933899                return EINVAL;
    934         }
    935 
     900       
    936901        /* If sizes are equal, nothing has to be done. */
    937902        aoff64_t old_size = ext4_inode_get_size(sb, inode_ref->inode);
    938         if (old_size == new_size) {
     903        if (old_size == new_size)
    939904                return EOK;
    940         }
    941 
     905       
    942906        /* It's not suppported to make the larger file by truncate operation */
    943         if (old_size < new_size) {
     907        if (old_size < new_size)
    944908                return EINVAL;
    945         }
    946 
     909       
    947910        /* Compute how many blocks will be released */
    948911        aoff64_t size_diff = old_size - new_size;
    949912        uint32_t block_size  = ext4_superblock_get_block_size(sb);
    950913        uint32_t diff_blocks_count = size_diff / block_size;
    951         if (size_diff % block_size != 0) {
     914        if (size_diff % block_size != 0)
    952915                diff_blocks_count++;
    953         }
    954 
     916       
    955917        uint32_t old_blocks_count = old_size / block_size;
    956         if (old_size % block_size != 0) {
     918        if (old_size % block_size != 0)
    957919                old_blocks_count++;
    958         }
    959 
    960         if (ext4_superblock_has_feature_incompatible(
    961                         inode_ref->fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    962                                 ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
    963 
     920       
     921        if ((ext4_superblock_has_feature_incompatible(inode_ref->fs->superblock,
     922            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     923            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
    964924                /* Extents require special operation */
    965 
    966                 rc = ext4_extent_release_blocks_from(inode_ref,
    967                                 old_blocks_count - diff_blocks_count);
    968                 if (rc != EOK) {
    969                         return rc;
    970                 }
     925                int rc = ext4_extent_release_blocks_from(inode_ref,
     926                    old_blocks_count - diff_blocks_count);
     927                if (rc != EOK)
     928                        return rc;
    971929        } else {
    972 
    973930                /* Release data blocks from the end of file */
    974 
     931               
    975932                /* Starting from 1 because of logical blocks are numbered from 0 */
    976933                for (uint32_t i = 1; i <= diff_blocks_count; ++i) {
    977                         rc = ext4_filesystem_release_inode_block(inode_ref, old_blocks_count - i);
    978                         if (rc != EOK) {
     934                        int rc = ext4_filesystem_release_inode_block(inode_ref,
     935                            old_blocks_count - i);
     936                        if (rc != EOK)
    979937                                return rc;
    980                         }
    981938                }
    982939        }
    983 
     940       
    984941        /* Update i-node */
    985942        ext4_inode_set_size(inode_ref->inode, new_size);
    986943        inode_ref->dirty = true;
    987 
     944       
    988945        return EOK;
    989946}
     
    991948/** Get physical block address by logical index of the block.
    992949 *
    993  * @param inode_ref             i-node to read block address from
    994  * @param iblock                logical index of block
    995  * @param fblock                output pointer for return physical block address
    996  * @return                              error code
     950 * @param inode_ref I-node to read block address from
     951 * @param iblock    Logical index of block
     952 * @param fblock    Output pointer for return physical block address
     953 *
     954 * @return Error code
     955 *
    997956 */
    998957int ext4_filesystem_get_inode_data_block_index(ext4_inode_ref_t *inode_ref,
    999                 aoff64_t iblock, uint32_t *fblock)
    1000 {
    1001         int rc;
    1002 
     958    aoff64_t iblock, uint32_t *fblock)
     959{
    1003960        ext4_filesystem_t *fs = inode_ref->fs;
    1004 
     961       
    1005962        /* For empty file is situation simple */
    1006963        if (ext4_inode_get_size(fs->superblock, inode_ref->inode) == 0) {
     
    1008965                return EOK;
    1009966        }
    1010 
     967       
    1011968        uint32_t current_block;
    1012 
     969       
    1013970        /* Handle i-node using extents */
    1014         if (ext4_superblock_has_feature_incompatible(fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    1015                         ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
    1016 
    1017                 rc = ext4_extent_find_block(inode_ref, iblock, &current_block);
    1018 
    1019                 if (rc != EOK) {
    1020                         return rc;
    1021                 }
    1022 
     971        if ((ext4_superblock_has_feature_incompatible(fs->superblock,
     972            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     973            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
     974                int rc = ext4_extent_find_block(inode_ref, iblock, &current_block);
     975                if (rc != EOK)
     976                        return rc;
     977               
    1023978                *fblock = current_block;
    1024979                return EOK;
    1025 
    1026         }
    1027 
     980        }
     981       
    1028982        ext4_inode_t *inode = inode_ref->inode;
    1029 
     983       
    1030984        /* Direct block are read directly from array in i-node structure */
    1031985        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
    1032                 current_block = ext4_inode_get_direct_block(inode, (uint32_t)iblock);
     986                current_block = ext4_inode_get_direct_block(inode, (uint32_t) iblock);
    1033987                *fblock = current_block;
    1034988                return EOK;
    1035989        }
    1036 
     990       
    1037991        /* Determine indirection level of the target block */
    1038         int level = -1;
    1039         for (int i = 1; i < 4; i++) {
     992        unsigned int level = 0;
     993        for (unsigned int i = 1; i < 4; i++) {
    1040994                if (iblock < fs->inode_block_limits[i]) {
    1041995                        level = i;
     
    1043997                }
    1044998        }
    1045 
    1046         if (level == -1) {
     999       
     1000        if (level == 0)
    10471001                return EIO;
    1048         }
    1049 
     1002       
    10501003        /* Compute offsets for the topmost level */
    1051         aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1];
    1052         current_block = ext4_inode_get_indirect_block(inode, level-1);
    1053         uint32_t offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
    1054 
     1004        aoff64_t block_offset_in_level =
     1005            iblock - fs->inode_block_limits[level - 1];
     1006        current_block = ext4_inode_get_indirect_block(inode, level - 1);
     1007        uint32_t offset_in_block =
     1008            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1009       
    10551010        /* Sparse file */
    10561011        if (current_block == 0) {
     
    10581013                return EOK;
    10591014        }
    1060 
     1015       
    10611016        block_t *block;
    1062 
    1063         /* Navigate through other levels, until we find the block number
     1017       
     1018        /*
     1019         * Navigate through other levels, until we find the block number
    10641020         * or find null reference meaning we are dealing with sparse file
    10651021         */
    10661022        while (level > 0) {
    1067 
    10681023                /* Load indirect block */
    1069                 rc = block_get(&block, fs->device, current_block, 0);
    1070                 if (rc != EOK) {
    1071                         return rc;
    1072                 }
    1073 
     1024                int rc = block_get(&block, fs->device, current_block, 0);
     1025                if (rc != EOK)
     1026                        return rc;
     1027               
    10741028                /* Read block address from indirect block */
    1075                 current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]);
    1076 
     1029                current_block =
     1030                    uint32_t_le2host(((uint32_t *) block->data)[offset_in_block]);
     1031               
    10771032                /* Put back indirect block untouched */
    10781033                rc = block_put(block);
    1079                 if (rc != EOK) {
    1080                         return rc;
    1081                 }
    1082 
     1034                if (rc != EOK)
     1035                        return rc;
     1036               
    10831037                /* Check for sparse file */
    10841038                if (current_block == 0) {
     
    10861040                        return EOK;
    10871041                }
    1088 
     1042               
    10891043                /* Jump to the next level */
    1090                 level -= 1;
    1091 
     1044                level--;
     1045               
    10921046                /* Termination condition - we have address of data block loaded */
    1093                 if (level == 0) {
     1047                if (level == 0)
    10941048                        break;
    1095                 }
    1096 
     1049               
    10971050                /* Visit the next level */
    10981051                block_offset_in_level %= fs->inode_blocks_per_level[level];
    1099                 offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
    1100         }
    1101 
     1052                offset_in_block =
     1053                    block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1054        }
     1055       
    11021056        *fblock = current_block;
    1103 
     1057       
    11041058        return EOK;
    11051059}
     
    11071061/** Set physical block address for the block logical address into the i-node.
    11081062 *
    1109  * @param inode_ref             i-node to set block address to
    1110  * @param iblock                logical index of block
    1111  * @param fblock                physical block address
    1112  * @return                              error code
     1063 * @param inode_ref I-node to set block address to
     1064 * @param iblock    Logical index of block
     1065 * @param fblock    Physical block address
     1066 *
     1067 * @return Error code
     1068 *
    11131069 */
    11141070int ext4_filesystem_set_inode_data_block_index(ext4_inode_ref_t *inode_ref,
    1115                 aoff64_t iblock, uint32_t fblock)
    1116 {
    1117         int rc;
    1118 
     1071    aoff64_t iblock, uint32_t fblock)
     1072{
    11191073        ext4_filesystem_t *fs = inode_ref->fs;
    1120 
     1074       
    11211075        /* Handle inode using extents */
    1122         if (ext4_superblock_has_feature_compatible(fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    1123                         ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
    1124                 /* not reachable !!! */
     1076        if ((ext4_superblock_has_feature_compatible(fs->superblock,
     1077            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     1078            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
     1079                /* Not reachable */
    11251080                return ENOTSUP;
    11261081        }
    1127 
     1082       
    11281083        /* Handle simple case when we are dealing with direct reference */
    11291084        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
    1130                 ext4_inode_set_direct_block(inode_ref->inode, (uint32_t)iblock, fblock);
     1085                ext4_inode_set_direct_block(inode_ref->inode, (uint32_t) iblock, fblock);
    11311086                inode_ref->dirty = true;
     1087               
    11321088                return EOK;
    11331089        }
    1134 
     1090       
    11351091        /* Determine the indirection level needed to get the desired block */
    1136         int level = -1;
    1137         for (int i = 1; i < 4; i++) {
     1092        unsigned int level = 0;
     1093        for (unsigned int i = 1; i < 4; i++) {
    11381094                if (iblock < fs->inode_block_limits[i]) {
    11391095                        level = i;
     
    11411097                }
    11421098        }
    1143 
    1144         if (level == -1) {
     1099       
     1100        if (level == 0)
    11451101                return EIO;
    1146         }
    1147 
     1102       
    11481103        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    1149 
     1104       
    11501105        /* Compute offsets for the topmost level */
    1151         aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1];
    1152         uint32_t current_block = ext4_inode_get_indirect_block(inode_ref->inode, level-1);
    1153         uint32_t offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
    1154 
     1106        aoff64_t block_offset_in_level =
     1107            iblock - fs->inode_block_limits[level - 1];
     1108        uint32_t current_block =
     1109            ext4_inode_get_indirect_block(inode_ref->inode, level - 1);
     1110        uint32_t offset_in_block =
     1111            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1112       
    11551113        uint32_t new_block_addr;
    1156         block_t *block, *new_block;
    1157 
     1114        block_t *block;
     1115        block_t *new_block;
     1116       
    11581117        /* Is needed to allocate indirect block on the i-node level */
    11591118        if (current_block == 0) {
    1160 
    11611119                /* Allocate new indirect block */
    1162                 rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
    1163                 if (rc != EOK) {
    1164                         return rc;
    1165                 }
    1166 
     1120                int rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
     1121                if (rc != EOK)
     1122                        return rc;
     1123               
    11671124                /* Update i-node */
    1168                 ext4_inode_set_indirect_block(inode_ref->inode, level - 1, new_block_addr);
     1125                ext4_inode_set_indirect_block(inode_ref->inode, level - 1,
     1126                    new_block_addr);
    11691127                inode_ref->dirty = true;
    1170 
     1128               
    11711129                /* Load newly allocated block */
    1172                 rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD);
     1130                rc = block_get(&new_block, fs->device, new_block_addr,
     1131                    BLOCK_FLAGS_NOREAD);
    11731132                if (rc != EOK) {
    11741133                        ext4_balloc_free_block(inode_ref, new_block_addr);
    11751134                        return rc;
    11761135                }
    1177 
     1136               
    11781137                /* Initialize new block */
    11791138                memset(new_block->data, 0, block_size);
    11801139                new_block->dirty = true;
    1181 
     1140               
    11821141                /* Put back the allocated block */
    11831142                rc = block_put(new_block);
    1184                 if (rc != EOK) {
    1185                         return rc;
    1186                 }
    1187 
     1143                if (rc != EOK)
     1144                        return rc;
     1145               
    11881146                current_block = new_block_addr;
    11891147        }
    1190 
    1191         /* Navigate through other levels, until we find the block number
     1148       
     1149        /*
     1150         * Navigate through other levels, until we find the block number
    11921151         * or find null reference meaning we are dealing with sparse file
    11931152         */
    11941153        while (level > 0) {
    1195 
    1196                 rc = block_get(&block, fs->device, current_block, 0);
    1197                 if (rc != EOK) {
    1198                         return rc;
    1199                 }
    1200 
    1201                 current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]);
    1202 
     1154                int rc = block_get(&block, fs->device, current_block, 0);
     1155                if (rc != EOK)
     1156                        return rc;
     1157               
     1158                current_block =
     1159                    uint32_t_le2host(((uint32_t *) block->data)[offset_in_block]);
     1160               
    12031161                if ((level > 1) && (current_block == 0)) {
    1204 
    12051162                        /* Allocate new block */
    12061163                        rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
     
    12091166                                return rc;
    12101167                        }
    1211 
     1168                       
    12121169                        /* Load newly allocated block */
    1213                         rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD);
     1170                        rc = block_get(&new_block, fs->device, new_block_addr,
     1171                            BLOCK_FLAGS_NOREAD);
    12141172                        if (rc != EOK) {
    12151173                                block_put(block);
    12161174                                return rc;
    12171175                        }
    1218 
     1176                       
    12191177                        /* Initialize allocated block */
    12201178                        memset(new_block->data, 0, block_size);
    12211179                        new_block->dirty = true;
    1222 
     1180                       
    12231181                        rc = block_put(new_block);
    12241182                        if (rc != EOK) {
     
    12261184                                return rc;
    12271185                        }
    1228 
     1186                       
    12291187                        /* Write block address to the parent */
    1230                         ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(new_block_addr);
     1188                        ((uint32_t *) block->data)[offset_in_block] =
     1189                            host2uint32_t_le(new_block_addr);
    12311190                        block->dirty = true;
    12321191                        current_block = new_block_addr;
    12331192                }
    1234 
     1193               
    12351194                /* Will be finished, write the fblock address */
    12361195                if (level == 1) {
    1237                         ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(fblock);
     1196                        ((uint32_t *) block->data)[offset_in_block] =
     1197                            host2uint32_t_le(fblock);
    12381198                        block->dirty = true;
    12391199                }
    1240 
     1200               
    12411201                rc = block_put(block);
    1242                 if (rc != EOK) {
    1243                         return rc;
    1244                 }
    1245 
    1246                 level -= 1;
    1247 
    1248                 /* If we are on the last level, break here as
     1202                if (rc != EOK)
     1203                        return rc;
     1204               
     1205                level--;
     1206               
     1207                /*
     1208                 * If we are on the last level, break here as
    12491209                 * there is no next level to visit
    12501210                 */
    1251                 if (level == 0) {
     1211                if (level == 0)
    12521212                        break;
    1253                 }
    1254 
     1213               
    12551214                /* Visit the next level */
    12561215                block_offset_in_level %= fs->inode_blocks_per_level[level];
    1257                 offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
    1258         }
    1259 
     1216                offset_in_block =
     1217                    block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1218        }
     1219       
    12601220        return EOK;
    12611221}
     
    12631223/** Release data block from i-node
    12641224 *
    1265  * @param inode_ref     i-node to release block from
    1266  * @param iblock                logical block to be released
    1267  * @return                              error code
    1268  */
    1269 int ext4_filesystem_release_inode_block(
    1270                 ext4_inode_ref_t *inode_ref, uint32_t iblock)
    1271 {
    1272         int rc;
    1273 
     1225 * @param inode_ref I-node to release block from
     1226 * @param iblock    Logical block to be released
     1227 *
     1228 * @return Error code
     1229 *
     1230 */
     1231int ext4_filesystem_release_inode_block(ext4_inode_ref_t *inode_ref,
     1232    uint32_t iblock)
     1233{
    12741234        uint32_t fblock;
    1275 
     1235       
    12761236        ext4_filesystem_t *fs = inode_ref->fs;
    1277 
    1278         /* EXTENTS are handled otherwise = there is not support in this function */
    1279         assert(! (ext4_superblock_has_feature_incompatible(fs->superblock,
    1280                         EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    1281                         ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)));
    1282 
     1237       
     1238        /* Extents are handled otherwise = there is not support in this function */
     1239        assert(!(ext4_superblock_has_feature_incompatible(fs->superblock,
     1240            EXT4_FEATURE_INCOMPAT_EXTENTS) &&
     1241            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))));
     1242       
    12831243        ext4_inode_t *inode = inode_ref->inode;
    1284 
     1244       
    12851245        /* Handle simple case when we are dealing with direct reference */
    12861246        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
    12871247                fblock = ext4_inode_get_direct_block(inode, iblock);
     1248               
    12881249                /* Sparse file */
    1289                 if (fblock == 0) {
     1250                if (fblock == 0)
    12901251                        return EOK;
    1291                 }
    1292 
     1252               
    12931253                ext4_inode_set_direct_block(inode, iblock, 0);
    12941254                return ext4_balloc_free_block(inode_ref, fblock);
    12951255        }
    1296 
    1297 
     1256       
    12981257        /* Determine the indirection level needed to get the desired block */
    1299         int level = -1;
    1300         for (int i = 1; i < 4; i++) {
     1258        unsigned int level = 0;
     1259        for (unsigned int i = 1; i < 4; i++) {
    13011260                if (iblock < fs->inode_block_limits[i]) {
    13021261                        level = i;
     
    13041263                }
    13051264        }
    1306 
    1307         if (level == -1) {
     1265       
     1266        if (level == 0)
    13081267                return EIO;
    1309         }
    1310 
     1268       
    13111269        /* Compute offsets for the topmost level */
    1312         aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1];
    1313         uint32_t current_block = ext4_inode_get_indirect_block(inode, level-1);
    1314         uint32_t offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
    1315 
    1316         /* Navigate through other levels, until we find the block number
     1270        aoff64_t block_offset_in_level =
     1271            iblock - fs->inode_block_limits[level - 1];
     1272        uint32_t current_block =
     1273            ext4_inode_get_indirect_block(inode, level - 1);
     1274        uint32_t offset_in_block =
     1275            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1276       
     1277        /*
     1278         * Navigate through other levels, until we find the block number
    13171279         * or find null reference meaning we are dealing with sparse file
    13181280         */
    13191281        block_t *block;
    13201282        while (level > 0) {
    1321                 rc = block_get(&block, fs->device, current_block, 0);
    1322                 if (rc != EOK) {
    1323                         return rc;
    1324                 }
    1325 
    1326                 current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]);
    1327 
     1283                int rc = block_get(&block, fs->device, current_block, 0);
     1284                if (rc != EOK)
     1285                        return rc;
     1286               
     1287                current_block =
     1288                    uint32_t_le2host(((uint32_t *) block->data)[offset_in_block]);
     1289               
    13281290                /* Set zero if physical data block address found */
    13291291                if (level == 1) {
    1330                         ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(0);
     1292                        ((uint32_t *) block->data)[offset_in_block] =
     1293                            host2uint32_t_le(0);
    13311294                        block->dirty = true;
    13321295                }
    1333 
     1296               
    13341297                rc = block_put(block);
    1335                 if (rc != EOK) {
    1336                         return rc;
    1337                 }
    1338 
    1339                 level -= 1;
    1340 
    1341                 /* If we are on the last level, break here as
     1298                if (rc != EOK)
     1299                        return rc;
     1300               
     1301                level--;
     1302               
     1303                /*
     1304                 * If we are on the last level, break here as
    13421305                 * there is no next level to visit
    13431306                 */
    1344                 if (level == 0) {
     1307                if (level == 0)
    13451308                        break;
    1346                 }
    1347 
     1309               
    13481310                /* Visit the next level */
    13491311                block_offset_in_level %= fs->inode_blocks_per_level[level];
    1350                 offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
    1351         }
    1352 
     1312                offset_in_block =
     1313                    block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1314        }
     1315       
    13531316        fblock = current_block;
    1354 
    1355         if (fblock == 0) {
     1317        if (fblock == 0)
    13561318                return EOK;
    1357         }
    1358 
     1319       
    13591320        /* Physical block is not referenced, it can be released */
    1360 
    13611321        return ext4_balloc_free_block(inode_ref, fblock);
    1362 
    13631322}
    13641323
    13651324/** Append following logical block to the i-node.
    13661325 *
    1367  * @param inode_ref                     i-node to append block to
    1368  * @param fblock                        output physical block address of newly allocated block
    1369  * @param iblock                        output logical number of newly allocated block
    1370  * @return                                      error code
     1326 * @param inode_ref I-node to append block to
     1327 * @param fblock    Output physical block address of newly allocated block
     1328 * @param iblock    Output logical number of newly allocated block
     1329 *
     1330 * @return Error code
     1331 *
    13711332 */
    13721333int ext4_filesystem_append_inode_block(ext4_inode_ref_t *inode_ref,
    1373                 uint32_t *fblock, uint32_t *iblock)
    1374 {
    1375         int rc;
    1376 
     1334    uint32_t *fblock, uint32_t *iblock)
     1335{
    13771336        /* Handle extents separately */
    1378         if (ext4_superblock_has_feature_incompatible(
    1379                         inode_ref->fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    1380                         ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
    1381 
     1337        if ((ext4_superblock_has_feature_incompatible(inode_ref->fs->superblock,
     1338            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     1339            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)))
    13821340                return ext4_extent_append_block(inode_ref, iblock, fblock, true);
    1383 
    1384         }
    1385 
     1341       
    13861342        ext4_superblock_t *sb = inode_ref->fs->superblock;
    1387 
     1343       
    13881344        /* Compute next block index and allocate data block */
    13891345        uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
    13901346        uint32_t block_size = ext4_superblock_get_block_size(sb);
    1391 
     1347       
    13921348        /* Align size i-node size */
    1393         if ((inode_size % block_size) != 0) {
     1349        if ((inode_size % block_size) != 0)
    13941350                inode_size += block_size - (inode_size % block_size);
    1395         }
    1396 
     1351       
    13971352        /* Logical blocks are numbered from 0 */
    13981353        uint32_t new_block_idx = inode_size / block_size;
    1399 
     1354       
    14001355        /* Allocate new physical block */
    14011356        uint32_t phys_block;
    1402         rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
    1403         if (rc != EOK) {
     1357        int rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
     1358        if (rc != EOK)
    14041359                return rc;
    1405         }
    1406 
     1360       
    14071361        /* Add physical block address to the i-node */
    1408         rc = ext4_filesystem_set_inode_data_block_index(inode_ref, new_block_idx, phys_block);
     1362        rc = ext4_filesystem_set_inode_data_block_index(inode_ref,
     1363            new_block_idx, phys_block);
    14091364        if (rc != EOK) {
    14101365                ext4_balloc_free_block(inode_ref, phys_block);
    14111366                return rc;
    14121367        }
    1413 
     1368       
    14141369        /* Update i-node */
    14151370        ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
    14161371        inode_ref->dirty = true;
    1417 
     1372       
    14181373        *fblock = phys_block;
    14191374        *iblock = new_block_idx;
    1420 
     1375       
    14211376        return EOK;
    14221377}
     
    14241379/**
    14251380 * @}
    1426  */ 
     1381 */
  • uspace/lib/ext4/libext4_filesystem.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_FILESYSTEM_H_
     
    3737#include "libext4_types.h"
    3838
    39 extern int ext4_filesystem_init(ext4_filesystem_t *,
    40                 service_id_t, enum cache_mode);
    41 extern int ext4_filesystem_fini(ext4_filesystem_t *fs);
    42 extern int ext4_filesystem_check_sanity(ext4_filesystem_t *fs);
     39extern int ext4_filesystem_init(ext4_filesystem_t *, service_id_t,
     40    enum cache_mode);
     41extern int ext4_filesystem_fini(ext4_filesystem_t *);
     42extern int ext4_filesystem_check_sanity(ext4_filesystem_t *);
    4343extern int ext4_filesystem_check_features(ext4_filesystem_t *, bool *);
    4444extern uint32_t ext4_filesystem_blockaddr2_index_in_group(ext4_superblock_t *,
    45                 uint32_t);
     45    uint32_t);
    4646extern uint32_t ext4_filesystem_index_in_group2blockaddr(ext4_superblock_t *,
    47                 uint32_t, uint32_t);
     47    uint32_t, uint32_t);
    4848extern int ext4_filesystem_get_block_group_ref(ext4_filesystem_t *, uint32_t,
    4949    ext4_block_group_ref_t **);
    5050extern int ext4_filesystem_put_block_group_ref(ext4_block_group_ref_t *);
    5151extern int ext4_filesystem_get_inode_ref(ext4_filesystem_t *, uint32_t,
    52                 ext4_inode_ref_t **);
     52    ext4_inode_ref_t **);
    5353extern int ext4_filesystem_put_inode_ref(ext4_inode_ref_t *);
    54 extern int ext4_filesystem_alloc_inode(ext4_filesystem_t *,
    55                 ext4_inode_ref_t **, int);
     54extern int ext4_filesystem_alloc_inode(ext4_filesystem_t *, ext4_inode_ref_t **,
     55    int);
    5656extern int ext4_filesystem_free_inode(ext4_inode_ref_t *);
    5757extern int ext4_filesystem_truncate_inode(ext4_inode_ref_t *, aoff64_t);
    5858extern int ext4_filesystem_get_inode_data_block_index(ext4_inode_ref_t *,
    59                 aoff64_t iblock, uint32_t *);
     59    aoff64_t iblock, uint32_t *);
    6060extern int ext4_filesystem_set_inode_data_block_index(ext4_inode_ref_t *,
    61                 aoff64_t, uint32_t);
    62 extern int ext4_filesystem_release_inode_block(
    63                 ext4_inode_ref_t *, uint32_t);
    64 extern int ext4_filesystem_append_inode_block(ext4_inode_ref_t *,
    65                 uint32_t *, uint32_t *);
     61    aoff64_t, uint32_t);
     62extern int ext4_filesystem_release_inode_block(ext4_inode_ref_t *, uint32_t);
     63extern int ext4_filesystem_append_inode_block(ext4_inode_ref_t *, uint32_t *,
     64    uint32_t *);
    6665
    6766#endif
  • uspace/lib/ext4/libext4_hash.c

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        libext4_hash.c
    35  * @brief       Hashing algorithms for ext4 HTree.
     33 * @file  libext4_hash.c
     34 * @brief Hashing algorithms for ext4 HTree.
    3635 */
    3736
    3837#include <errno.h>
    3938#include <mem.h>
    40 
    4139#include "libext4.h"
    4240
    43 #define TEA_DELTA 0x9E3779B9
    44 
     41#define TEA_DELTA  0x9E3779B9
    4542
    4643/* F, G and H are basic MD4 functions: selection, majority, parity */
    47 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
    48 #define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
    49 #define H(x, y, z) ((x) ^ (y) ^ (z))
    50 
     44#define F(x, y, z)  ((z) ^ ((x) & ((y) ^ (z))))
     45#define G(x, y, z)  (((x) & (y)) + (((x) ^ (y)) & (z)))
     46#define H(x, y, z)  ((x) ^ (y) ^ (z))
    5147
    5248/*
     
    5652 * Rotation is separate from addition to prevent recomputation
    5753 */
    58 #define ROUND(f, a, b, c, d, x, s)      \
    59         (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s)))
    60 #define K1 0
    61 #define K2 013240474631UL
    62 #define K3 015666365641UL
    63 
     54#define ROUND(f, a, b, c, d, x, s) \
     55        (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s)))
     56
     57#define K1  0
     58#define K2  013240474631UL
     59#define K3  015666365641UL
    6460
    6561static void tea_transform(uint32_t buf[4], uint32_t const in[])
    6662{
    6763        uint32_t sum = 0;
    68         uint32_t b0 = buf[0], b1 = buf[1];
    69         uint32_t a = in[0], b = in[1], c = in[2], d = in[3];
     64        uint32_t b0 = buf[0];
     65        uint32_t b1 = buf[1];
     66        uint32_t a = in[0];
     67        uint32_t b = in[1];
     68        uint32_t c = in[2];
     69        uint32_t d = in[3];
     70       
    7071        int n = 16;
    71 
     72       
    7273        do {
    7374                sum += TEA_DELTA;
    74                 b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
    75                 b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
     75                b0 += ((b1 << 4) + a) ^ (b1 + sum) ^ ((b1 >> 5) + b);
     76                b1 += ((b0 << 4) + c) ^ (b0 + sum) ^ ((b0 >> 5) + d);
    7677        } while (--n);
    77 
     78       
    7879        buf[0] += b0;
    7980        buf[1] += b1;
     
    8485{
    8586        uint32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3];
    86 
     87       
    8788        /* Round 1 */
    8889        ROUND(F, a, b, c, d, in[0] + K1,  3);
     
    9495        ROUND(F, c, d, a, b, in[6] + K1, 11);
    9596        ROUND(F, b, c, d, a, in[7] + K1, 19);
    96 
     97       
    9798        /* Round 2 */
    9899        ROUND(G, a, b, c, d, in[1] + K2,  3);
     
    104105        ROUND(G, c, d, a, b, in[4] + K2,  9);
    105106        ROUND(G, b, c, d, a, in[6] + K2, 13);
    106 
     107       
    107108        /* Round 3 */
    108109        ROUND(H, a, b, c, d, in[3] + K3,  3);
     
    114115        ROUND(H, c, d, a, b, in[0] + K3, 11);
    115116        ROUND(H, b, c, d, a, in[4] + K3, 15);
    116 
     117       
    117118        buf[0] += a;
    118119        buf[1] += b;
    119120        buf[2] += c;
    120121        buf[3] += d;
    121 
    122122}
    123123
    124124static uint32_t hash_unsigned(const char *name, int len)
    125125{
    126         uint32_t hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
     126        uint32_t hash;
     127        uint32_t hash0 = 0x12a3fe2d;
     128        uint32_t hash1 = 0x37abe8f9;
    127129        const unsigned char *ucp = (const unsigned char *) name;
    128 
     130       
    129131        while (len--) {
    130132                hash = hash1 + (hash0 ^ (((int) *ucp++) * 7152373));
    131 
    132                 if (hash & 0x80000000) {
     133               
     134                if (hash & 0x80000000)
    133135                        hash -= 0x7fffffff;
    134                 }
     136               
    135137                hash1 = hash0;
    136138                hash0 = hash;
    137139        }
     140       
    138141        return hash0 << 1;
    139142}
     
    141144static uint32_t hash_signed(const char *name, int len)
    142145{
    143         uint32_t hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
     146        uint32_t hash;
     147        uint32_t hash0 = 0x12a3fe2d;
     148        uint32_t hash1 = 0x37abe8f9;
    144149        const signed char *scp = (const signed char *) name;
    145 
     150       
    146151        while (len--) {
    147152                hash = hash1 + (hash0 ^ (((int) *scp++) * 7152373));
    148 
    149                 if (hash & 0x80000000) {
     153               
     154                if (hash & 0x80000000)
    150155                        hash -= 0x7fffffff;
    151                 }
     156               
    152157                hash1 = hash0;
    153158                hash0 = hash;
    154159        }
     160       
    155161        return hash0 << 1;
    156162}
     
    161167        int i;
    162168        const signed char *scp = (const signed char *) msg;
    163 
    164         pad = (uint32_t)len | ((uint32_t)len << 8);
     169       
     170        pad = (uint32_t) len | ((uint32_t) len << 8);
    165171        pad |= pad << 16;
    166 
     172       
    167173        val = pad;
    168         if (len > num*4) {
     174        if (len > num * 4)
    169175                len = num * 4;
    170         }
    171 
     176       
    172177        for (i = 0; i < len; i++) {
    173                 if ((i % 4) == 0) {
     178                if ((i % 4) == 0)
    174179                        val = pad;
    175                 }
     180               
    176181                val = ((int) scp[i]) + (val << 8);
    177182                if ((i % 4) == 3) {
     
    181186                }
    182187        }
    183 
    184         if (--num >= 0) {
     188       
     189        if (--num >= 0)
    185190                *buf++ = val;
    186         }
    187 
    188         while (--num >= 0) {
     191       
     192        while (--num >= 0)
    189193                *buf++ = pad;
    190         }
    191 }
    192 
    193 
    194 static void str2hashbuf_unsigned(const char *msg, int len, uint32_t *buf, int num)
     194}
     195
     196static void str2hashbuf_unsigned(const char *msg, int len, uint32_t *buf,
     197    int num)
    195198{
    196199        uint32_t pad, val;
    197200        int i;
    198201        const unsigned char *ucp = (const unsigned char *) msg;
    199 
    200         pad = (uint32_t)len | ((uint32_t)len << 8);
     202       
     203        pad = (uint32_t) len | ((uint32_t) len << 8);
    201204        pad |= pad << 16;
    202 
     205       
    203206        val = pad;
    204         if (len > num*4) {
    205         len = num * 4;
    206         }
    207 
     207        if (len > num * 4)
     208                len = num * 4;
     209       
    208210        for (i = 0; i < len; i++) {
    209                 if ((i % 4) == 0) {
     211                if ((i % 4) == 0)
    210212                        val = pad;
    211                 }
     213               
    212214                val = ((int) ucp[i]) + (val << 8);
    213215                if ((i % 4) == 3) {
     
    217219                }
    218220        }
    219 
    220         if (--num >= 0) {
     221       
     222        if (--num >= 0)
    221223                *buf++ = val;
    222         }
    223 
    224         while (--num >= 0) {
     224       
     225        while (--num >= 0)
    225226                *buf++ = pad;
    226         }
    227 }
    228 
     227}
    229228
    230229/** Compute hash value of the string.
    231230 *
    232  * @param hinfo         hash info structure with information about
    233  *                                      the algorithm, hash seed and with the place
    234  *                                      for the output hash value
    235  * @param len           length of the name
    236  * @param name          name to be hashed
    237  * @return                      error code
     231 * @param hinfo Hash info structure with information about
     232 *              the algorithm, hash seed and with the place
     233 *              for the output hash value
     234 * @param len  Length of the name
     235 * @param name Name to be hashed
     236 *
     237 * @return Error code
     238 *
    238239 */
    239240int ext4_hash_string(ext4_hash_info_t *hinfo, int len, const char *name)
     
    242243        uint32_t minor_hash = 0;
    243244        const char *p;
    244     int i;
    245     uint32_t in[8], buf[4];
    246     void (*str2hashbuf)(const char *, int, uint32_t *, int) = str2hashbuf_signed;
    247 
    248     /* Initialize the default seed for the hash checksum functions */
     245        int i;
     246        uint32_t in[8], buf[4];
     247        void (*str2hashbuf)(const char *, int, uint32_t *, int) =
     248            str2hashbuf_signed;
     249       
     250        /* Initialize the default seed for the hash checksum functions */
    249251        buf[0] = 0x67452301;
    250252        buf[1] = 0xefcdab89;
    251253        buf[2] = 0x98badcfe;
    252254        buf[3] = 0x10325476;
    253 
    254     /* Check if the seed is all zero's */
     255       
     256        /* Check if the seed is all zero's */
    255257        if (hinfo->seed) {
    256258                for (i = 0; i < 4; i++) {
    257                         if (hinfo->seed[i] != 0) {
    258                 break;
    259                         }
    260                 }
    261                 if (i < 4) {
     259                        if (hinfo->seed[i] != 0)
     260                                break;
     261                       
     262                }
     263               
     264                if (i < 4)
    262265                        memcpy(buf, hinfo->seed, sizeof(buf));
    263                 }
    264     }
    265 
     266        }
     267       
    266268        switch (hinfo->hash_version) {
    267                 case EXT4_HASH_VERSION_LEGACY_UNSIGNED:
    268                         hash = hash_unsigned(name, len);
    269                         break;
    270 
    271                 case EXT4_HASH_VERSION_LEGACY:
    272                         hash = hash_signed(name, len);
    273                         break;
    274 
    275 
    276                 case EXT4_HASH_VERSION_HALF_MD4_UNSIGNED:
    277                         str2hashbuf = str2hashbuf_unsigned;
    278 
    279                 case EXT4_HASH_VERSION_HALF_MD4:
    280                         p = name;
    281                         while (len > 0) {
    282                                 (*str2hashbuf)(p, len, in, 8);
    283                                 half_md4_transform(buf, in);
    284                                 len -= 32;
    285                                 p += 32;
    286                         }
    287                         minor_hash = buf[2];
    288                         hash = buf[1];
    289                         break;
    290 
    291 
    292                 case EXT4_HASH_VERSION_TEA_UNSIGNED:
    293                         str2hashbuf = str2hashbuf_unsigned;
    294 
    295                 case EXT4_HASH_VERSION_TEA:
    296                         p = name;
    297                         while (len > 0) {
    298                                 (*str2hashbuf)(p, len, in, 4);
    299                                 tea_transform(buf, in);
    300                                 len -= 16;
    301                                 p += 16;
    302                         }
    303                         hash = buf[0];
    304                         minor_hash = buf[1];
    305                         break;
    306 
    307                 default:
    308                         hinfo->hash = 0;
    309                         return EINVAL;
    310         }
    311 
     269        case EXT4_HASH_VERSION_LEGACY_UNSIGNED:
     270                hash = hash_unsigned(name, len);
     271                break;
     272        case EXT4_HASH_VERSION_LEGACY:
     273                hash = hash_signed(name, len);
     274                break;
     275        case EXT4_HASH_VERSION_HALF_MD4_UNSIGNED:
     276                str2hashbuf = str2hashbuf_unsigned;
     277        case EXT4_HASH_VERSION_HALF_MD4:
     278                p = name;
     279               
     280                while (len > 0) {
     281                        (*str2hashbuf)(p, len, in, 8);
     282                        half_md4_transform(buf, in);
     283                        len -= 32;
     284                        p += 32;
     285                }
     286               
     287                minor_hash = buf[2];
     288                hash = buf[1];
     289                break;
     290        case EXT4_HASH_VERSION_TEA_UNSIGNED:
     291                str2hashbuf = str2hashbuf_unsigned;
     292        case EXT4_HASH_VERSION_TEA:
     293                p = name;
     294               
     295                while (len > 0) {
     296                        (*str2hashbuf)(p, len, in, 4);
     297                        tea_transform(buf, in);
     298                        len -= 16;
     299                        p += 16;
     300                }
     301               
     302                hash = buf[0];
     303                minor_hash = buf[1];
     304                break;
     305        default:
     306                hinfo->hash = 0;
     307                return EINVAL;
     308        }
     309       
    312310        hash = hash & ~1;
    313         if (hash == (EXT4_DIRECTORY_HTREE_EOF << 1)) {
    314                 hash = (EXT4_DIRECTORY_HTREE_EOF-1) << 1;
    315         }
    316 
     311        if (hash == (EXT4_DIRECTORY_HTREE_EOF << 1))
     312                hash = (EXT4_DIRECTORY_HTREE_EOF - 1) << 1;
     313       
    317314        hinfo->hash = hash;
    318315        hinfo->minor_hash = minor_hash;
    319 
     316       
    320317        return EOK;
    321318}
     
    323320/**
    324321 * @}
    325  */ 
     322 */
  • uspace/lib/ext4/libext4_hash.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_HASH_H_
  • uspace/lib/ext4/libext4_ialloc.c

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        libext4_ialloc.c
    35  * @brief       Inode (de)allocation operations.
     33 * @file  libext4_ialloc.c
     34 * @brief I-node (de)allocation operations.
    3635 */
    3736
     
    4342/** Convert i-node number to relative index in block group.
    4443 *
    45  * @param sb    superblock
    46  * @param inode i-node number to be converted
    47  * @return              index of the i-node in the block group
     44 * @param sb    Superblock
     45 * @param inode I-node number to be converted
     46 *
     47 * @return Index of the i-node in the block group
     48 *
    4849 */
    4950static uint32_t ext4_ialloc_inode2index_in_group(ext4_superblock_t *sb,
    50                 uint32_t inode)
     51    uint32_t inode)
    5152{
    5253        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
     
    5657/** Convert relative index of i-node to absolute i-node number.
    5758 *
    58  * @param sb    superblock
    59  * @param inode index to be converted
    60  * @return              absolute number of the i-node
     59 * @param sb    Superblock
     60 * @param inode Index to be converted
     61 *
     62 * @return Absolute number of the i-node
     63 *
    6164 */
    6265static uint32_t ext4_ialloc_index_in_group2inode(ext4_superblock_t *sb,
    63                 uint32_t index, uint32_t bgid)
     66    uint32_t index, uint32_t bgid)
    6467{
    6568        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
     
    6972/** Compute block group number from the i-node number.
    7073 *
    71  * @param sb            superblock
    72  * @param inode         i-node number to be found the block group for
    73  * @return                      block group number computed from i-node number
     74 * @param sb    Superblock
     75 * @param inode I-node number to be found the block group for
     76 *
     77 * @return Block group number computed from i-node number
     78 *
    7479 */
    7580static uint32_t ext4_ialloc_get_bgid_of_inode(ext4_superblock_t *sb,
    76                 uint32_t inode)
     81    uint32_t inode)
    7782{
    7883        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
    7984        return (inode - 1) / inodes_per_group;
    80 
    8185}
    8286
     
    8488/** Free i-node number and modify filesystem data structers.
    8589 *
    86  * @param fs            filesystem, where the i-node is located
    87  * @param index         index of i-node to be release
    88  * @param is_dir        flag us for information whether i-node is directory or not
     90 * @param fs     Filesystem, where the i-node is located
     91 * @param index  Index of i-node to be release
     92 * @param is_dir Flag us for information whether i-node is directory or not
     93 *
    8994 */
    9095int ext4_ialloc_free_inode(ext4_filesystem_t *fs, uint32_t index, bool is_dir)
    9196{
    92         int rc;
    93 
    9497        ext4_superblock_t *sb = fs->superblock;
    95 
     98       
    9699        /* Compute index of block group and load it */
    97100        uint32_t block_group = ext4_ialloc_get_bgid_of_inode(sb, index);
    98 
     101       
    99102        ext4_block_group_ref_t *bg_ref;
    100         rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
    101         if (rc != EOK) {
    102                 return rc;
    103         }
    104 
     103        int rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
     104        if (rc != EOK)
     105                return rc;
     106       
    105107        /* Load i-node bitmap */
    106108        uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
    107                         bg_ref->block_group, sb);
     109            bg_ref->block_group, sb);
    108110        block_t *bitmap_block;
    109         rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, BLOCK_FLAGS_NONE);
    110         if (rc != EOK) {
    111                 return rc;
    112         }
    113 
     111        rc = block_get(&bitmap_block, fs->device, bitmap_block_addr,
     112            BLOCK_FLAGS_NONE);
     113        if (rc != EOK)
     114                return rc;
     115       
    114116        /* Free i-node in the bitmap */
    115117        uint32_t index_in_group = ext4_ialloc_inode2index_in_group(sb, index);
    116118        ext4_bitmap_free_bit(bitmap_block->data, index_in_group);
    117119        bitmap_block->dirty = true;
    118 
     120       
    119121        /* Put back the block with bitmap */
    120122        rc = block_put(bitmap_block);
     
    124126                return rc;
    125127        }
    126 
     128       
    127129        /* If released i-node is a directory, decrement used directories count */
    128130        if (is_dir) {
    129131                uint32_t bg_used_dirs = ext4_block_group_get_used_dirs_count(
    130                         bg_ref->block_group, sb);
     132                    bg_ref->block_group, sb);
    131133                bg_used_dirs--;
    132                 ext4_block_group_set_used_dirs_count(
    133                                 bg_ref->block_group, sb, bg_used_dirs);
     134                ext4_block_group_set_used_dirs_count(bg_ref->block_group, sb,
     135                    bg_used_dirs);
    134136        }
    135 
     137       
    136138        /* Update block group free inodes count */
    137139        uint32_t free_inodes = ext4_block_group_get_free_inodes_count(
    138                         bg_ref->block_group, sb);
     140            bg_ref->block_group, sb);
    139141        free_inodes++;
    140         ext4_block_group_set_free_inodes_count(bg_ref->block_group,
    141                         sb, free_inodes);
    142 
     142        ext4_block_group_set_free_inodes_count(bg_ref->block_group, sb,
     143            free_inodes);
     144       
    143145        bg_ref->dirty = true;
    144 
     146       
    145147        /* Put back the modified block group */
    146148        rc = ext4_filesystem_put_block_group_ref(bg_ref);
    147         if (rc != EOK) {
    148                 return rc;
    149         }
    150 
     149        if (rc != EOK)
     150                return rc;
     151       
    151152        /* Update superblock free inodes count */
    152         uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
     153        uint32_t sb_free_inodes =
     154            ext4_superblock_get_free_inodes_count(sb);
    153155        sb_free_inodes++;
    154156        ext4_superblock_set_free_inodes_count(sb, sb_free_inodes);
    155 
     157       
    156158        return EOK;
    157159}
     
    159161/** I-node allocation algorithm.
    160162 *
    161  * This is more simple algorithm, than Orlov allocator used in the Linux kernel
    162  *
    163  * @param fs            filesystem to allocate i-node on
    164  * @param index         output value - allocated i-node number
    165  * @param is_dir        flag if allocated i-node will be file or directory
    166  * @return                      error code
     163 * This is more simple algorithm, than Orlov allocator used
     164 * in the Linux kernel.
     165 *
     166 * @param fs     Filesystem to allocate i-node on
     167 * @param index  Output value - allocated i-node number
     168 * @param is_dir Flag if allocated i-node will be file or directory
     169 *
     170 * @return Error code
     171 *
    167172 */
    168173int ext4_ialloc_alloc_inode(ext4_filesystem_t *fs, uint32_t *index, bool is_dir)
    169174{
    170         int rc;
    171 
    172175        ext4_superblock_t *sb = fs->superblock;
    173 
     176       
    174177        uint32_t bgid = 0;
    175178        uint32_t bg_count = ext4_superblock_get_block_group_count(sb);
    176179        uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
    177180        uint32_t avg_free_inodes = sb_free_inodes / bg_count;
    178 
     181       
    179182        /* Try to find free i-node in all block groups */
    180183        while (bgid < bg_count) {
    181 
    182184                /* Load block group to check */
    183185                ext4_block_group_ref_t *bg_ref;
    184                 rc = ext4_filesystem_get_block_group_ref(fs, bgid, &bg_ref);
    185                 if (rc != EOK) {
     186                int rc = ext4_filesystem_get_block_group_ref(fs, bgid, &bg_ref);
     187                if (rc != EOK)
    186188                        return rc;
    187                 }
    188 
     189               
    189190                ext4_block_group_t *bg = bg_ref->block_group;
    190 
     191               
    191192                /* Read necessary values for algorithm */
    192193                uint32_t free_blocks = ext4_block_group_get_free_blocks_count(bg, sb);
    193194                uint32_t free_inodes = ext4_block_group_get_free_inodes_count(bg, sb);
    194195                uint32_t used_dirs = ext4_block_group_get_used_dirs_count(bg, sb);
    195 
     196               
    196197                /* Check if this block group is good candidate for allocation */
    197198                if ((free_inodes >= avg_free_inodes) && (free_blocks > 0)) {
    198 
    199199                        /* Load block with bitmap */
    200                         uint32_t bitmap_block_addr =  ext4_block_group_get_inode_bitmap(
    201                                         bg_ref->block_group, sb);
    202 
     200                        uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
     201                            bg_ref->block_group, sb);
     202                       
    203203                        block_t *bitmap_block;
    204                         rc = block_get(&bitmap_block, fs->device,
    205                                         bitmap_block_addr, BLOCK_FLAGS_NONE);
    206                         if (rc != EOK) {
     204                        rc = block_get(&bitmap_block, fs->device, bitmap_block_addr,
     205                            BLOCK_FLAGS_NONE);
     206                        if (rc != EOK)
    207207                                return rc;
    208                         }
    209 
     208                       
    210209                        /* Try to allocate i-node in the bitmap */
    211210                        uint32_t inodes_in_group = ext4_superblock_get_inodes_in_group(sb, bgid);
    212211                        uint32_t index_in_group;
    213                         rc = ext4_bitmap_find_free_bit_and_set(
    214                                         bitmap_block->data, 0, &index_in_group, inodes_in_group);
    215 
     212                        rc = ext4_bitmap_find_free_bit_and_set(bitmap_block->data,
     213                            0, &index_in_group, inodes_in_group);
     214                       
    216215                        /* Block group has not any free i-node */
    217216                        if (rc == ENOSPC) {
     
    220219                                continue;
    221220                        }
    222 
     221                       
    223222                        /* Free i-node found, save the bitmap */
    224223                        bitmap_block->dirty = true;
    225 
     224                       
    226225                        rc = block_put(bitmap_block);
    227                         if (rc != EOK) {
     226                        if (rc != EOK)
    228227                                return rc;
    229                         }
    230 
     228                       
    231229                        /* Modify filesystem counters */
    232230                        free_inodes--;
    233231                        ext4_block_group_set_free_inodes_count(bg, sb, free_inodes);
    234 
     232                       
    235233                        /* Increment used directories counter */
    236234                        if (is_dir) {
     
    238236                                ext4_block_group_set_used_dirs_count(bg, sb, used_dirs);
    239237                        }
    240 
     238                       
    241239                        /* Decrease unused inodes count */
    242240                        if (ext4_block_group_has_flag(bg,
    243                                 EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
    244 
     241                            EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
    245242                                uint32_t unused =
    246                                                 ext4_block_group_get_itable_unused(bg, sb);
    247 
     243                                    ext4_block_group_get_itable_unused(bg, sb);
     244                               
    248245                                uint32_t inodes_in_group =
    249                                                 ext4_superblock_get_inodes_in_group(sb, bgid);
    250 
     246                                    ext4_superblock_get_inodes_in_group(sb, bgid);
     247                               
    251248                                uint32_t free = inodes_in_group - unused;
    252 
     249                               
    253250                                if (index_in_group >= free) {
    254251                                        unused = inodes_in_group - (index_in_group + 1);
    255 
    256252                                        ext4_block_group_set_itable_unused(bg, sb, unused);
    257253                                }
    258254                        }
    259 
     255                       
    260256                        /* Save modified block group */
    261257                        bg_ref->dirty = true;
    262 
     258                       
    263259                        rc = ext4_filesystem_put_block_group_ref(bg_ref);
    264                         if (rc != EOK) {
     260                        if (rc != EOK)
    265261                                return rc;
    266                         }
    267 
     262                       
    268263                        /* Update superblock */
    269264                        sb_free_inodes--;
    270265                        ext4_superblock_set_free_inodes_count(sb, sb_free_inodes);
    271 
     266                       
    272267                        /* Compute the absolute i-nodex number */
    273268                        *index = ext4_ialloc_index_in_group2inode(sb, index_in_group, bgid);
    274 
     269                       
    275270                        return EOK;
    276 
    277271                }
    278 
     272               
    279273                /* Block group not modified, put it and jump to the next block group */
    280274                ext4_filesystem_put_block_group_ref(bg_ref);
    281275                ++bgid;
    282276        }
    283 
     277       
    284278        return ENOSPC;
    285279}
     
    287281/**
    288282 * @}
    289  */ 
     283 */
  • uspace/lib/ext4/libext4_ialloc.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_IALLOC_H_
     
    3838extern int ext4_ialloc_free_inode(ext4_filesystem_t *, uint32_t, bool);
    3939extern int ext4_ialloc_alloc_inode(ext4_filesystem_t *, uint32_t *, bool);
     40
    4041#endif
    4142
  • uspace/lib/ext4/libext4_inode.c

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        libext4_inode.c
    35  * @brief       Ext4 inode structure operations.
     33 * @file  libext4_inode.c
     34 * @brief Ext4 i-node structure operations.
    3635 */
    3736
     
    4342/** Compute number of bits for block count.
    4443 *
    45  *  @param block_size   filesystem block_size
    46  *  @return             number of bits
     44 *  @param block_size Filesystem block_size
     45 *
     46 *  @return Number of bits
     47 *
    4748 */
    4849static uint32_t ext4_inode_block_bits_count(uint32_t block_size)
     
    5051        uint32_t bits = 8;
    5152        uint32_t size = block_size;
    52 
     53       
    5354        do {
    5455                bits++;
    5556                size = size >> 1;
    5657        } while (size > 256);
    57 
     58       
    5859        return bits;
    5960}
     
    6162/** Get mode of the i-node.
    6263 *
    63  * @param sb            superblock
    64  * @param inode         i-node to load mode from
    65  * @return              mode of the i-node
     64 * @param sb    Superblock
     65 * @param inode I-node to load mode from
     66 *
     67 * @return Mode of the i-node
     68 *
    6669 */
    6770uint32_t ext4_inode_get_mode(ext4_superblock_t *sb, ext4_inode_t *inode)
    6871{
    6972        if (ext4_superblock_get_creator_os(sb) == EXT4_SUPERBLOCK_OS_HURD) {
    70                 return ((uint32_t)uint16_t_le2host(inode->osd2.hurd2.mode_high)) << 16 |
    71                     ((uint32_t)uint16_t_le2host(inode->mode));
     73                return ((uint32_t) uint16_t_le2host(inode->osd2.hurd2.mode_high)) << 16 |
     74                    ((uint32_t) uint16_t_le2host(inode->mode));
    7275        }
     76       
    7377        return uint16_t_le2host(inode->mode);
    7478}
     
    7680/** Set mode of the i-node.
    7781 *
    78  * @param sb            superblock
    79  * @param inode         i-node to set mode to
    80  * @param mode          mode to set to i-node
     82 * @param sb    Superblock
     83 * @param inode I-node to set mode to
     84 * @param mode  Mode to set to i-node
     85 *
    8186 */
    8287void ext4_inode_set_mode(ext4_superblock_t *sb, ext4_inode_t *inode, uint32_t mode)
    8388{
    8489        inode->mode = host2uint16_t_le((mode << 16) >> 16);
    85 
    86         if (ext4_superblock_get_creator_os(sb) == EXT4_SUPERBLOCK_OS_HURD) {
     90       
     91        if (ext4_superblock_get_creator_os(sb) == EXT4_SUPERBLOCK_OS_HURD)
    8792                inode->osd2.hurd2.mode_high = host2uint16_t_le(mode >> 16);
    88         }
    8993}
    9094
    9195/** Get ID of the i-node owner (user id).
    9296 *
    93  * @param inode         i-node to load uid from
    94  * @return              user ID of the i-node owner
     97 * @param inode I-node to load uid from
     98 *
     99 * @return User ID of the i-node owner
     100 *
    95101 */
    96102uint32_t ext4_inode_get_uid(ext4_inode_t *inode)
     
    101107/** Set ID of the i-node owner.
    102108 *
    103  * @param inode         i-node to set uid to
    104  * @param uid           ID of the i-node owner
     109 * @param inode I-node to set uid to
     110 * @param uid   ID of the i-node owner
     111 *
    105112 */
    106113void ext4_inode_set_uid(ext4_inode_t *inode, uint32_t uid)
     
    111118/** Get real i-node size.
    112119 *
    113  * @param sb            superblock
    114  * @param inode         i-node to load size from
    115  * @return              real size of i-node
     120 * @param sb    Superblock
     121 * @param inode I-node to load size from
     122 *
     123 * @return Real size of i-node
     124 *
    116125 */
    117126uint64_t ext4_inode_get_size(ext4_superblock_t *sb, ext4_inode_t *inode)
    118127{
    119128        uint32_t major_rev = ext4_superblock_get_rev_level(sb);
    120 
    121         if ((major_rev > 0) && ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)) {
     129       
     130        if ((major_rev > 0) &&
     131            (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)))
    122132                return ((uint64_t)uint32_t_le2host(inode->size_hi)) << 32 |
    123                             ((uint64_t)uint32_t_le2host(inode->size_lo));
    124         }
     133                    ((uint64_t)uint32_t_le2host(inode->size_lo));
     134       
    125135        return uint32_t_le2host(inode->size_lo);
    126136}
     
    128138/** Set real i-node size.
    129139 *
    130  *  @param inode        inode to set size to
    131  *  @param size         size of the i-node
    132  */
    133 void ext4_inode_set_size(ext4_inode_t *inode, uint64_t size) {
     140 * @param inode I-node to set size to
     141 * @param size  Size of the i-node
     142 *
     143 */
     144void ext4_inode_set_size(ext4_inode_t *inode, uint64_t size)
     145{
    134146        inode->size_lo = host2uint32_t_le((size << 32) >> 32);
    135147        inode->size_hi = host2uint32_t_le(size >> 32);
     
    138150/** Get time, when i-node was last accessed.
    139151 *
    140  * @param inode         i-node
    141  * @return                      time of the last access (POSIX)
     152 * @param inode I-node
     153 *
     154 * @return Time of the last access (POSIX)
     155 *
    142156 */
    143157uint32_t ext4_inode_get_access_time(ext4_inode_t *inode)
     
    148162/** Set time, when i-node was last accessed.
    149163 *
    150  * @param inode         i-node
    151  * @param time          time of the last access (POSIX)
     164 * @param inode I-node
     165 * @param time  Time of the last access (POSIX)
     166 *
    152167 */
    153168void ext4_inode_set_access_time(ext4_inode_t *inode, uint32_t time)
     
    158173/** Get time, when i-node was last changed.
    159174 *
    160  * @param inode         i-node
    161  * @return                      time of the last change (POSIX)
     175 * @param inode I-node
     176 *
     177 * @return Time of the last change (POSIX)
     178 *
    162179 */
    163180uint32_t ext4_inode_get_change_inode_time(ext4_inode_t *inode)
     
    168185/** Set time, when i-node was last changed.
    169186 *
    170  * @param inode         i-node
    171  * @param time          time of the last change (POSIX)
     187 * @param inode I-node
     188 * @param time  Time of the last change (POSIX)
     189 *
    172190 */
    173191void ext4_inode_set_change_inode_time(ext4_inode_t *inode, uint32_t time)
     
    178196/** Get time, when i-node content was last modified.
    179197 *
    180  * @param inode         i-node
    181  * @return                      time of the last content modification (POSIX)
     198 * @param inode I-node
     199 *
     200 * @return Time of the last content modification (POSIX)
     201 *
    182202 */
    183203uint32_t ext4_inode_get_modification_time(ext4_inode_t *inode)
     
    188208/** Set time, when i-node content was last modified.
    189209 *
    190  * @param inode         i-node
    191  * @param time          time of the last content modification (POSIX)
     210 * @param inode I-node
     211 * @param time  Time of the last content modification (POSIX)
     212 *
    192213 */
    193214void ext4_inode_set_modification_time(ext4_inode_t *inode, uint32_t time)
     
    198219/** Get time, when i-node was deleted.
    199220 *
    200  * @param inode         i-node
    201  * @return                      time of the delete action (POSIX)
     221 * @param inode I-node
     222 *
     223 * @return Time of the delete action (POSIX)
     224 *
    202225 */
    203226uint32_t ext4_inode_get_deletion_time(ext4_inode_t *inode)
     
    208231/** Set time, when i-node was deleted.
    209232 *
    210  * @param inode         i-node
    211  * @param time          time of the delete action (POSIX)
     233 * @param inode I-node
     234 * @param time  Time of the delete action (POSIX)
     235 *
    212236 */
    213237void ext4_inode_set_deletion_time(ext4_inode_t *inode, uint32_t time)
     
    218242/** Get ID of the i-node owner's group.
    219243 *
    220  * @param inode         i-node to load gid from
    221  * @return              group ID of the i-node owner
     244 * @param inode I-node to load gid from
     245 *
     246 * @return Group ID of the i-node owner
     247 *
    222248 */
    223249uint32_t ext4_inode_get_gid(ext4_inode_t *inode)
     
    228254/** Set ID ot the i-node owner's group.
    229255 *
    230  * @param inode         i-node to set gid to
    231  * @param gid           group ID of the i-node owner
     256 * @param inode I-node to set gid to
     257 * @param gid   Group ID of the i-node owner
     258 *
    232259 */
    233260void ext4_inode_set_gid(ext4_inode_t *inode, uint32_t gid)
     
    238265/** Get number of links to i-node.
    239266 *
    240  * @param inode         i-node to load number of links from
    241  * @return              number of links to i-node
     267 * @param inode I-node to load number of links from
     268 *
     269 * @return Number of links to i-node
     270 *
    242271 */
    243272uint16_t ext4_inode_get_links_count(ext4_inode_t *inode)
     
    248277/** Set number of links to i-node.
    249278 *
    250  * @param inode         i-node to set number of links to
    251  * @param count         number of links to i-node
     279 * @param inode I-node to set number of links to
     280 * @param count Number of links to i-node
     281 *
    252282 */
    253283void ext4_inode_set_links_count(ext4_inode_t *inode, uint16_t count)
     
    258288/** Get number of 512-bytes blocks used for i-node.
    259289 *
    260  * @param sb            superblock
    261  * @param inode         i-node
    262  * @return                      number of 512-bytes blocks
     290 * @param sb    Superblock
     291 * @param inode I-node
     292 *
     293 * @return Number of 512-bytes blocks
     294 *
    263295 */
    264296uint64_t ext4_inode_get_blocks_count(ext4_superblock_t *sb, ext4_inode_t *inode)
    265297{
    266         if (ext4_superblock_has_feature_read_only(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
    267 
     298        if (ext4_superblock_has_feature_read_only(sb,
     299            EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
    268300                /* 48-bit field */
    269                 uint64_t count = ((uint64_t)uint16_t_le2host(inode->osd2.linux2.blocks_high)) << 32 |
    270                                 uint32_t_le2host(inode->blocks_count_lo);
    271 
     301                uint64_t count = ((uint64_t)
     302                    uint16_t_le2host(inode->osd2.linux2.blocks_high)) << 32 |
     303                    uint32_t_le2host(inode->blocks_count_lo);
     304               
    272305                if (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_HUGE_FILE)) {
    273                 uint32_t block_size = ext4_superblock_get_block_size(sb);
    274                 uint32_t block_bits = ext4_inode_block_bits_count(block_size);
    275                         return count  << (block_bits - 9);
    276                 } else {
     306                        uint32_t block_size = ext4_superblock_get_block_size(sb);
     307                        uint32_t block_bits = ext4_inode_block_bits_count(block_size);
     308                        return count << (block_bits - 9);
     309                } else
    277310                        return count;
    278                 }
     311        } else
     312                return uint32_t_le2host(inode->blocks_count_lo);
     313}
     314
     315/** Set number of 512-bytes blocks used for i-node.
     316 *
     317 * @param sb    Superblock
     318 * @param inode I-node
     319 * @param count Number of 512-bytes blocks
     320 *
     321 * @return Error code
     322 *
     323 */
     324int ext4_inode_set_blocks_count(ext4_superblock_t *sb, ext4_inode_t *inode,
     325    uint64_t count)
     326{
     327        /* 32-bit maximum */
     328        uint64_t max = 0;
     329        max = ~max >> 32;
     330       
     331        if (count <= max) {
     332                inode->blocks_count_lo = host2uint32_t_le(count);
     333                inode->osd2.linux2.blocks_high = 0;
     334                ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
     335               
     336                return EOK;
     337        }
     338       
     339        /* Check if there can be used huge files (many blocks) */
     340        if (!ext4_superblock_has_feature_read_only(sb,
     341            EXT4_FEATURE_RO_COMPAT_HUGE_FILE))
     342                return EINVAL;
     343       
     344        /* 48-bit maximum */
     345        max = 0;
     346        max = ~max >> 16;
     347       
     348        if (count <= max) {
     349                inode->blocks_count_lo = host2uint32_t_le(count);
     350                inode->osd2.linux2.blocks_high = host2uint16_t_le(count >> 32);
     351                ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
    279352        } else {
    280                 return uint32_t_le2host(inode->blocks_count_lo);
    281     }
    282 }
    283 
    284 /** Set number of 512-bytes blocks used for i-node.
    285  *
    286  * @param sb            superblock
    287  * @param inode         i-node
    288  * @param count         number of 512-bytes blocks
    289  * @return                      error code
    290  */
    291 int ext4_inode_set_blocks_count(ext4_superblock_t *sb, ext4_inode_t *inode,
    292                 uint64_t count)
    293 {
    294     /* 32-bit maximum */
    295     uint64_t max = 0;
    296     max = ~max >> 32;
    297 
    298     if (count <= max) {
    299         inode->blocks_count_lo = host2uint32_t_le(count);
    300         inode->osd2.linux2.blocks_high = 0;
    301         ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
    302         return EOK;
    303     }
    304 
    305     /* Check if there can be used huge files (many blocks) */
    306     if (!ext4_superblock_has_feature_read_only(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
    307         return EINVAL;
    308     }
    309 
    310     /* 48-bit maximum */
    311     max = 0;
    312     max = ~max >> 16;
    313 
    314     if (count <= max) {
    315         inode->blocks_count_lo = host2uint32_t_le(count);
    316         inode->osd2.linux2.blocks_high = host2uint16_t_le(count >> 32);
    317         ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
    318     } else {
    319         uint32_t block_size = ext4_superblock_get_block_size(sb);
    320         uint32_t block_bits = ext4_inode_block_bits_count(block_size);
    321         ext4_inode_set_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
    322         count = count >> (block_bits - 9);
    323         inode->blocks_count_lo = host2uint32_t_le(count);
    324         inode->osd2.linux2.blocks_high = host2uint16_t_le(count >> 32);
    325     }
    326     return EOK;
     353                uint32_t block_size = ext4_superblock_get_block_size(sb);
     354                uint32_t block_bits = ext4_inode_block_bits_count(block_size);
     355                ext4_inode_set_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
     356                count = count >> (block_bits - 9);
     357                inode->blocks_count_lo = host2uint32_t_le(count);
     358                inode->osd2.linux2.blocks_high = host2uint16_t_le(count >> 32);
     359        }
     360       
     361        return EOK;
    327362}
    328363
    329364/** Get flags (features) of i-node.
    330  *
    331  * @param inode         i-node to get flags from
    332  * @return              flags (bitmap)
    333  */
    334 uint32_t ext4_inode_get_flags(ext4_inode_t *inode) {
     365 *
     366 * @param inode I-node to get flags from
     367 *
     368 * @return Flags (bitmap)
     369 *
     370 */
     371uint32_t ext4_inode_get_flags(ext4_inode_t *inode)
     372{
    335373        return uint32_t_le2host(inode->flags);
    336374}
     
    338376/** Set flags (features) of i-node.
    339377 *
    340  * @param inode         i-node to set flags to
    341  * @param flags         flags to set to i-node
    342  */
    343 void ext4_inode_set_flags(ext4_inode_t *inode, uint32_t flags) {
     378 * @param inode I-node to set flags to
     379 * @param flags Flags to set to i-node
     380 *
     381 */
     382void ext4_inode_set_flags(ext4_inode_t *inode, uint32_t flags)
     383{
    344384        inode->flags = host2uint32_t_le(flags);
    345385}
     
    347387/** Get file generation (used by NFS).
    348388 *
    349  * @param inode         i-node
    350  * @return                      file generation
     389 * @param inode I-node
     390 *
     391 * @return File generation
     392 *
    351393 */
    352394uint32_t ext4_inode_get_generation(ext4_inode_t *inode)
     
    357399/** Set file generation (used by NFS).
    358400 *
    359  * @param inode                 i-node
    360  * @param generation    file generation
     401 * @param inode      I-node
     402 * @param generation File generation
     403 *
    361404 */
    362405void ext4_inode_set_generation(ext4_inode_t *inode, uint32_t generation)
     
    367410/** Get address of block, where are extended attributes located.
    368411 *
    369  * @param inode                 i-node
    370  * @param sb                    superblock
    371  * @return                              block address
     412 * @param inode I-node
     413 * @param sb    Superblock
     414 *
     415 * @return Block address
     416 *
    372417 */
    373418uint64_t ext4_inode_get_file_acl(ext4_inode_t *inode, ext4_superblock_t *sb)
    374419{
    375         if (ext4_superblock_get_creator_os(sb) == EXT4_SUPERBLOCK_OS_LINUX) {
    376                 return ((uint32_t)uint16_t_le2host(inode->osd2.linux2.file_acl_high)) << 16 |
     420        if (ext4_superblock_get_creator_os(sb) == EXT4_SUPERBLOCK_OS_LINUX)
     421                return ((uint32_t)
     422                    uint16_t_le2host(inode->osd2.linux2.file_acl_high)) << 16 |
    377423                    (uint32_t_le2host(inode->file_acl_lo));
    378         }
    379 
     424       
    380425        return uint32_t_le2host(inode->file_acl_lo);
    381426}
     
    383428/** Set address of block, where are extended attributes located.
    384429 *
    385  * @param inode                 i-node
    386  * @param sb                    superblock
    387  * @param file_acl              block address
     430 * @param inode    I-node
     431 * @param sb       Superblock
     432 * @param file_acl Block address
     433 *
    388434 */
    389435void ext4_inode_set_file_acl(ext4_inode_t *inode, ext4_superblock_t *sb,
    390                 uint64_t file_acl)
     436    uint64_t file_acl)
    391437{
    392438        inode->file_acl_lo = host2uint32_t_le((file_acl << 32) >> 32);
    393 
    394         if (ext4_superblock_get_creator_os(sb) == EXT4_SUPERBLOCK_OS_LINUX) {
     439       
     440        if (ext4_superblock_get_creator_os(sb) == EXT4_SUPERBLOCK_OS_LINUX)
    395441                inode->osd2.linux2.file_acl_high = host2uint16_t_le(file_acl >> 32);
    396         }
    397 }
    398 
    399 /***********************************************************************/
     442}
    400443
    401444/** Get block address of specified direct block.
    402445 *
    403  * @param inode         i-node to load block from
    404  * @param idx           index of logical block
    405  * @return              physical block address
     446 * @param inode I-node to load block from
     447 * @param idx   Index of logical block
     448 *
     449 * @return Physical block address
     450 *
    406451 */
    407452uint32_t ext4_inode_get_direct_block(ext4_inode_t *inode, uint32_t idx)
    408453{
    409454        assert(idx < EXT4_INODE_DIRECT_BLOCK_COUNT);
     455       
    410456        return uint32_t_le2host(inode->blocks[idx]);
    411457}
     
    413459/** Set block address of specified direct block.
    414460 *
    415  * @param inode         i-node to set block address to
    416  * @param idx           index of logical block
    417  * @param fblock        physical block address
     461 * @param inode  I-node to set block address to
     462 * @param idx    Index of logical block
     463 * @param fblock Physical block address
     464 *
    418465 */
    419466void ext4_inode_set_direct_block(ext4_inode_t *inode, uint32_t idx, uint32_t fblock)
    420467{
    421468        assert(idx < EXT4_INODE_DIRECT_BLOCK_COUNT);
     469       
    422470        inode->blocks[idx] = host2uint32_t_le(fblock);
    423471}
     
    425473/** Get block address of specified indirect block.
    426474 *
    427  * @param inode         i-node to get block address from
    428  * @param idx           index of indirect block
    429  * @return              physical block address
     475 * @param inode I-node to get block address from
     476 * @param idx   Index of indirect block
     477 *
     478 * @return Physical block address
     479 *
    430480 */
    431481uint32_t ext4_inode_get_indirect_block(ext4_inode_t *inode, uint32_t idx)
     
    436486/** Set block address of specified indirect block.
    437487 *
    438  * @param inode         i-node to set block address to
    439  * @param idx           index of indirect block
    440  * @param fblock        physical block address
    441  */
    442 void ext4_inode_set_indirect_block(ext4_inode_t *inode, uint32_t idx, uint32_t fblock)
    443 {
    444         inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK] = host2uint32_t_le(fblock);
     488 * @param inode  I-node to set block address to
     489 * @param idx    Index of indirect block
     490 * @param fblock Physical block address
     491 *
     492 */
     493void ext4_inode_set_indirect_block(ext4_inode_t *inode, uint32_t idx,
     494    uint32_t fblock)
     495{
     496        inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK] =
     497            host2uint32_t_le(fblock);
    445498}
    446499
    447500/** Check if i-node has specified type.
    448501 *
    449  * @param sb            superblock
    450  * @param inode         i-node to check type of
    451  * @param type          type to check
    452  * @return              result of check operation
    453  */
    454 bool ext4_inode_is_type(ext4_superblock_t *sb, ext4_inode_t *inode, uint32_t type)
     502 * @param sb    Superblock
     503 * @param inode I-node to check type of
     504 * @param type  Type to check
     505 *
     506 * @return Result of check operation
     507 *
     508 */
     509bool ext4_inode_is_type(ext4_superblock_t *sb, ext4_inode_t *inode,
     510    uint32_t type)
    455511{
    456512        uint32_t mode = ext4_inode_get_mode(sb, inode);
     
    460516/** Get extent header from the root of the extent tree.
    461517 *
    462  * @param inode         i-node to get extent header from
    463  * @return              pointer to extent header of the root node
     518 * @param inode I-node to get extent header from
     519 *
     520 * @return Pointer to extent header of the root node
     521 *
    464522 */
    465523ext4_extent_header_t * ext4_inode_get_extent_header(ext4_inode_t *inode)
    466524{
    467         return (ext4_extent_header_t *)inode->blocks;
     525        return (ext4_extent_header_t *) inode->blocks;
    468526}
    469527
    470528/** Check if i-node has specified flag.
    471529 *
    472  * @param inode         i-node to check flags of
    473  * @param flag          flag to check
    474  * @return              result of check operation
     530 * @param inode I-node to check flags of
     531 * @param flag  Flag to check
     532 *
     533 * @return Result of check operation
     534 *
    475535 */
    476536bool ext4_inode_has_flag(ext4_inode_t *inode, uint32_t flag)
    477537{
    478         if (ext4_inode_get_flags(inode) & flag) {
     538        if (ext4_inode_get_flags(inode) & flag)
    479539                return true;
    480         }
     540       
    481541        return false;
    482542}
     
    484544/** Remove specified flag from i-node.
    485545 *
    486  * @param inode         i-node to clear flag on
    487  * @param clear_flag    flag to be cleared
     546 * @param inode      I-node to clear flag on
     547 * @param clear_flag Flag to be cleared
     548 *
    488549 */
    489550void ext4_inode_clear_flag(ext4_inode_t *inode, uint32_t clear_flag)
     
    496557/** Set specified flag to i-node.
    497558 *
    498  * @param inode         i-node to set flag on
    499  * @param set_flag      falt to be set
     559 * @param inode    I-node to set flag on
     560 * @param set_flag Flag to be set
     561 *
    500562 */
    501563void ext4_inode_set_flag(ext4_inode_t *inode, uint32_t set_flag)
     
    508570/** Check if i-node can be truncated.
    509571 *
    510  * @param sb            superblock
    511  * @param inode         i-node to check
    512  * @return              result of the check operation
     572 * @param sb    Superblock
     573 * @param inode I-node to check
     574 *
     575 * @return Result of the check operation
     576 *
    513577 */
    514578bool ext4_inode_can_truncate(ext4_superblock_t *sb, ext4_inode_t *inode)
    515579{
    516          if (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_APPEND)
    517                          || ext4_inode_has_flag(inode, EXT4_INODE_FLAG_IMMUTABLE)) {
    518                  return false;
    519          }
    520 
    521          if (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)
    522                          || ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_DIRECTORY)) {
    523                  return true;
    524          }
    525 
    526          return false;
     580        if ((ext4_inode_has_flag(inode, EXT4_INODE_FLAG_APPEND)) ||
     581            (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_IMMUTABLE)))
     582                return false;
     583       
     584        if ((ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)) ||
     585            (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_DIRECTORY)))
     586                return true;
     587       
     588        return false;
    527589}
    528590
    529591/**
    530592 * @}
    531  */ 
     593 */
  • uspace/lib/ext4/libext4_inode.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_INODE_H_
     
    5656extern uint16_t ext4_inode_get_links_count(ext4_inode_t *);
    5757extern void ext4_inode_set_links_count(ext4_inode_t *, uint16_t);
    58 extern uint64_t ext4_inode_get_blocks_count(ext4_superblock_t *, ext4_inode_t *);
    59 extern int ext4_inode_set_blocks_count(ext4_superblock_t *, ext4_inode_t *, uint64_t);
     58extern uint64_t ext4_inode_get_blocks_count(ext4_superblock_t *,
     59    ext4_inode_t *);
     60extern int ext4_inode_set_blocks_count(ext4_superblock_t *, ext4_inode_t *,
     61    uint64_t);
    6062extern uint32_t ext4_inode_get_flags(ext4_inode_t *);
    6163extern void ext4_inode_set_flags(ext4_inode_t *, uint32_t);
     
    6365extern void ext4_inode_set_generation(ext4_inode_t *, uint32_t);
    6466extern uint64_t ext4_inode_get_file_acl(ext4_inode_t *, ext4_superblock_t *);
    65 extern void ext4_inode_set_file_acl(ext4_inode_t *, ext4_superblock_t *, uint64_t);
    66 /*
    67 uint16_t extra_isize;
    68 uint32_t ctime_extra; // Extra change time (nsec << 2 | epoch)
    69 uint32_t mtime_extra; // Extra Modification time (nsec << 2 | epoch)
    70 uint32_t atime_extra; // Extra Access time (nsec << 2 | epoch)
    71 uint32_t crtime; // File creation time
    72 uint32_t crtime_extra; // Extra file creation time (nsec << 2 | epoch)
    73 uint32_t version_hi;   // High 32 bits for 64-bit version
    74 */
    75 
    76 /******************************************/
     67extern void ext4_inode_set_file_acl(ext4_inode_t *, ext4_superblock_t *,
     68    uint64_t);
    7769
    7870extern uint32_t ext4_inode_get_direct_block(ext4_inode_t *, uint32_t);
  • uspace/lib/ext4/libext4_superblock.c

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333/**
    34  * @file        libext4_superblock.c
    35  * @brief       Ext4 superblock operations.
     34 * @file  libext4_superblock.c
     35 * @brief Ext4 superblock operations.
    3636 */
    3737
     
    4444/** Get number of i-nodes in the whole filesystem.
    4545 *
    46  * @param sb            superblock
    47  * @return                      number of i-nodes
     46 * @param sb Superblock
     47 *
     48 * @return Number of i-nodes
     49 *
    4850 */
    4951uint32_t ext4_superblock_get_inodes_count(ext4_superblock_t *sb)
     
    5456/** Set number of i-nodes in the whole filesystem.
    5557 *
    56  * @param sb            superblock
    57  * @param count         number of i-nodes
     58 * @param sb    Superblock
     59 * @param count Number of i-nodes
     60 *
    5861 */
    5962void ext4_superblock_set_inodes_count(ext4_superblock_t *sb, uint32_t count)
     
    6467/** Get number of data blocks in the whole filesystem.
    6568 *
    66  * @param sb            superblock
    67  * @return                      number of data blocks
     69 * @param sb Superblock
     70 *
     71 * @return Number of data blocks
     72 *
    6873 */
    6974uint64_t ext4_superblock_get_blocks_count(ext4_superblock_t *sb)
    7075{
    71         return ((uint64_t)uint32_t_le2host(sb->blocks_count_hi) << 32) |
    72                         uint32_t_le2host(sb->blocks_count_lo);
     76        return ((uint64_t) uint32_t_le2host(sb->blocks_count_hi) << 32) |
     77            uint32_t_le2host(sb->blocks_count_lo);
    7378}
    7479
    7580/** Set number of data blocks in the whole filesystem.
    7681 *
    77  * @param sb            superblock
    78  * @param count         number of data blocks
     82 * @param sb    Superblock
     83 * @param count Number of data blocks
     84 *
    7985 */
    8086void ext4_superblock_set_blocks_count(ext4_superblock_t *sb, uint64_t count)
     
    8692/** Get number of reserved data blocks in the whole filesystem.
    8793 *
    88  * @param sb            superblock
    89  * @return                      number of reserved data blocks
     94 * @param sb Superblock
     95 *
     96 * @return Number of reserved data blocks
     97 *
    9098 */
    9199uint64_t ext4_superblock_get_reserved_blocks_count(ext4_superblock_t *sb)
    92100{
    93         return ((uint64_t)uint32_t_le2host(sb->reserved_blocks_count_hi) << 32) |
    94                         uint32_t_le2host(sb->reserved_blocks_count_lo);
     101        return ((uint64_t)
     102            uint32_t_le2host(sb->reserved_blocks_count_hi) << 32) |
     103            uint32_t_le2host(sb->reserved_blocks_count_lo);
    95104}
    96105
    97106/** Set number of reserved data blocks in the whole filesystem.
    98107 *
    99  * @param sb            superblock
    100  * @param count         number of reserved data blocks
    101  */
    102 void ext4_superblock_set_reserved_blocks_count(ext4_superblock_t *sb, uint64_t count)
     108 * @param sb    Superblock
     109 * @param count Number of reserved data blocks
     110 *
     111 */
     112void ext4_superblock_set_reserved_blocks_count(ext4_superblock_t *sb,
     113    uint64_t count)
    103114{
    104115        sb->reserved_blocks_count_lo = host2uint32_t_le((count << 32) >> 32);
     
    108119/** Get number of free data blocks in the whole filesystem.
    109120 *
    110  * @param sb            superblock
    111  * @return                      number of free data blocks
     121 * @param sb Superblock
     122 *
     123 * @return Number of free data blocks
     124 *
    112125 */
    113126uint64_t ext4_superblock_get_free_blocks_count(ext4_superblock_t *sb)
    114127{
    115         return ((uint64_t)uint32_t_le2host(sb->free_blocks_count_hi) << 32) |
    116                         uint32_t_le2host(sb->free_blocks_count_lo);
     128        return ((uint64_t)
     129            uint32_t_le2host(sb->free_blocks_count_hi) << 32) |
     130            uint32_t_le2host(sb->free_blocks_count_lo);
    117131}
    118132
    119133/** Set number of free data blocks in the whole filesystem.
    120134 *
    121  * @param sb            superblock
    122  * @param count         number of free data blocks
    123  */
    124 void ext4_superblock_set_free_blocks_count(ext4_superblock_t *sb, uint64_t count)
     135 * @param sb    Superblock
     136 * @param count Number of free data blocks
     137 *
     138 */
     139void ext4_superblock_set_free_blocks_count(ext4_superblock_t *sb,
     140    uint64_t count)
    125141{
    126142        sb->free_blocks_count_lo = host2uint32_t_le((count << 32) >> 32);
     
    130146/** Get number of free i-nodes in the whole filesystem.
    131147 *
    132  * @param sb            superblock
    133  * @return                      number of free i-nodes
     148 * @param sb Superblock
     149 *
     150 * @return Number of free i-nodes
     151 *
    134152 */
    135153uint32_t ext4_superblock_get_free_inodes_count(ext4_superblock_t *sb)
     
    140158/** Set number of free i-nodes in the whole filesystem.
    141159 *
    142  * @param sb            superblock
    143  * @param count         number of free i-nodes
    144  */
    145 void ext4_superblock_set_free_inodes_count(ext4_superblock_t *sb, uint32_t count)
     160 * @param sb    Superblock
     161 * @param count Number of free i-nodes
     162 *
     163 */
     164void ext4_superblock_set_free_inodes_count(ext4_superblock_t *sb,
     165    uint32_t count)
    146166{
    147167        sb->free_inodes_count = host2uint32_t_le(count);
    148168}
    149169
    150 /** Get index of first data block (block, where is located superblock)
    151  *
    152  * @param sb            superblock
    153  * @return                      index of the first data block
     170/** Get index of first data block (block where the superblock is located)
     171 *
     172 * @param sb Superblock
     173 *
     174 * @return Index of the first data block
     175 *
    154176 */
    155177uint32_t ext4_superblock_get_first_data_block(ext4_superblock_t *sb)
     
    158180}
    159181
    160 /** Set index of first data block (block, where is located superblock)
    161  *
    162  * @param sb            superblock
    163  * @param first         index of the first data block
    164  */
    165 void ext4_superblock_set_first_data_block(ext4_superblock_t *sb, uint32_t first)
     182/** Set index of first data block (block where the superblock is located)
     183 *
     184 * @param sb    Superblock
     185 * @param first Index of the first data block
     186 *
     187 */
     188void ext4_superblock_set_first_data_block(ext4_superblock_t *sb,
     189    uint32_t first)
    166190{
    167191        sb->first_data_block = host2uint32_t_le(first);
     
    170194/** Get logarithmic block size (1024 << size == block_size)
    171195 *
    172  * @param sb            superblock
    173  * @return                      logarithmic block size
     196 * @param sb Superblock
     197 *
     198 * @return Logarithmic block size
     199 *
    174200 */
    175201uint32_t ext4_superblock_get_log_block_size(ext4_superblock_t *sb)
     
    180206/** Set logarithmic block size (1024 << size == block_size)
    181207 *
    182  * @param sb            superblock
    183  * @return                      logarithmic block size
    184  */
    185 void ext4_superblock_set_log_block_size(ext4_superblock_t *sb, uint32_t log_size)
     208 * @param sb Superblock
     209 *
     210 * @return Logarithmic block size
     211 *
     212 */
     213void ext4_superblock_set_log_block_size(ext4_superblock_t *sb,
     214    uint32_t log_size)
    186215{
    187216        sb->log_block_size = host2uint32_t_le(log_size);
     
    190219/** Get size of data block (in bytes).
    191220 *
    192  * @param sb            superblock
    193  * @return                      size of data block
     221 * @param sb Superblock
     222 *
     223 * @return Size of data block
     224 *
    194225 */
    195226uint32_t ext4_superblock_get_block_size(ext4_superblock_t *sb)
     
    200231/** Set size of data block (in bytes).
    201232 *
    202  * @param sb            superblock
    203  * @param size          size of data block (must be power of 2, at least 1024)
     233 * @param sb   Superblock
     234 * @param size Size of data block (must be power of 2, at least 1024)
     235 *
    204236 */
    205237void ext4_superblock_set_block_size(ext4_superblock_t *sb, uint32_t size)
     
    207239        uint32_t log = 0;
    208240        uint32_t tmp = size / EXT4_MIN_BLOCK_SIZE;
    209 
     241       
    210242        tmp >>= 1;
    211243        while (tmp) {
     
    213245                tmp >>= 1;
    214246        }
    215 
     247       
    216248        ext4_superblock_set_log_block_size(sb, log);
    217249}
     
    219251/** Get logarithmic fragment size (1024 << size)
    220252 *
    221  * @param sb            superblock
    222  * @return                      logarithmic fragment size
     253 * @param sb Superblock
     254 *
     255 * @return Logarithmic fragment size
     256 *
    223257 */
    224258uint32_t ext4_superblock_get_log_frag_size(ext4_superblock_t *sb)
     
    229263/** Set logarithmic fragment size (1024 << size)
    230264 *
    231  * @param sb            superblock
    232  * @return                      logarithmic fragment size
    233  */
    234 
    235 void ext4_superblock_set_log_frag_size(ext4_superblock_t *sb, uint32_t frag_size)
     265 * @param sb        Superblock
     266 * @param frag_size Logarithmic fragment size
     267 *
     268 */
     269void ext4_superblock_set_log_frag_size(ext4_superblock_t *sb,
     270    uint32_t frag_size)
    236271{
    237272        sb->log_frag_size = host2uint32_t_le(frag_size);
     
    240275/** Get size of fragment (in bytes).
    241276 *
    242  * @param sb            superblock
    243  * @return                      size of fragment
     277 * @param sb Superblock
     278 *
     279 * @return Size of fragment
     280 *
    244281 */
    245282uint32_t ext4_superblock_get_frag_size(ext4_superblock_t *sb)
     
    250287/** Set size of fragment (in bytes).
    251288 *
    252  * @param sb            superblock
    253  * @param size          size of fragment (must be power of 2, at least 1024)
     289 * @param sb   Superblock
     290 * @param size Size of fragment (must be power of 2, at least 1024)
     291 *
    254292 */
    255293void ext4_superblock_set_frag_size(ext4_superblock_t *sb, uint32_t size)
     
    257295        uint32_t log = 0;
    258296        uint32_t tmp = size / EXT4_MIN_BLOCK_SIZE;
    259 
     297       
    260298        tmp >>= 1;
    261299        while (tmp) {
     
    263301                tmp >>= 1;
    264302        }
    265 
     303       
    266304        ext4_superblock_set_log_frag_size(sb, log);
    267305}
     
    269307/** Get number of data blocks per block group (except last BG)
    270308 *
    271  * @param sb            superblock
    272  * @return                      data blocks per block group
     309 * @param sb Superblock
     310 *
     311 * @return Data blocks per block group
     312 *
    273313 */
    274314uint32_t ext4_superblock_get_blocks_per_group(ext4_superblock_t *sb)
     
    279319/** Set number of data blocks per block group (except last BG)
    280320 *
    281  * @param sb            superblock
    282  * @param blocks        data blocks per block group
    283  */
    284 void ext4_superblock_set_blocks_per_group(ext4_superblock_t *sb, uint32_t blocks)
     321 * @param sb     Superblock
     322 * @param blocks Data blocks per block group
     323 *
     324 */
     325void ext4_superblock_set_blocks_per_group(ext4_superblock_t *sb,
     326    uint32_t blocks)
    285327{
    286328        sb->blocks_per_group = host2uint32_t_le(blocks);
     
    289331/** Get number of fragments per block group (except last BG)
    290332 *
    291  * @param sb            superblock
    292  * @return                      fragments per block group
     333 * @param sb Superblock
     334 *
     335 * @return Fragments per block group
     336 *
    293337 */
    294338uint32_t ext4_superblock_get_frags_per_group(ext4_superblock_t *sb)
     
    299343/** Set number of fragment per block group (except last BG)
    300344 *
    301  * @param sb            superblock
    302  * @param frags         fragments per block group
     345 * @param sb    Superblock
     346 * @param frags Fragments per block group
    303347 */
    304348void ext4_superblock_set_frags_per_group(ext4_superblock_t *sb, uint32_t frags)
     
    307351}
    308352
    309 
    310353/** Get number of i-nodes per block group (except last BG)
    311354 *
    312  * @param sb            superblock
    313  * @return                      i-nodes per block group
     355 * @param sb Superblock
     356 *
     357 * @return I-nodes per block group
     358 *
    314359 */
    315360uint32_t ext4_superblock_get_inodes_per_group(ext4_superblock_t *sb)
     
    320365/** Set number of i-nodes per block group (except last BG)
    321366 *
    322  * @param sb            superblock
    323  * @param inodes        i-nodes per block group
    324  */
    325 void ext4_superblock_set_inodes_per_group(ext4_superblock_t *sb, uint32_t inodes)
     367 * @param sb     Superblock
     368 * @param inodes I-nodes per block group
     369 *
     370 */
     371void ext4_superblock_set_inodes_per_group(ext4_superblock_t *sb,
     372    uint32_t inodes)
    326373{
    327374        sb->inodes_per_group = host2uint32_t_le(inodes);
     
    330377/** Get time when filesystem was mounted (POSIX time).
    331378 *
    332  * @param sb            superblock
    333  * @return                      mount time
     379 * @param sb Superblock
     380 *
     381 * @return Mount time
     382 *
    334383 */
    335384uint32_t ext4_superblock_get_mount_time(ext4_superblock_t *sb)
     
    340389/** Set time when filesystem was mounted (POSIX time).
    341390 *
    342  * @param sb            superblock
    343  * @param time          mount time
     391 * @param sb   Superblock
     392 * @param time Mount time
     393 *
    344394 */
    345395void ext4_superblock_set_mount_time(ext4_superblock_t *sb, uint32_t time)
     
    350400/** Get time when filesystem was last accesed by write operation (POSIX time).
    351401 *
    352  * @param sb            superblock
    353  * @return                      write time
     402 * @param sb Superblock
     403 *
     404 * @return Write time
     405 *
    354406 */
    355407uint32_t ext4_superblock_get_write_time(ext4_superblock_t *sb)
     
    360412/** Set time when filesystem was last accesed by write operation (POSIX time).
    361413 *
    362  * @param sb            superblock
    363  * @param time          write time
     414 * @param sb   Superblock
     415 * @param time Write time
     416 *
    364417 */
    365418void ext4_superblock_set_write_time(ext4_superblock_t *sb, uint32_t time)
     
    370423/** Get number of mount from last filesystem check.
    371424 *
    372  * @param sb            superblock
    373  * @return                      number of mounts
     425 * @param sb Superblock
     426 *
     427 * @return Number of mounts
     428 *
    374429 */
    375430uint16_t ext4_superblock_get_mount_count(ext4_superblock_t *sb)
     
    380435/** Set number of mount from last filesystem check.
    381436 *
    382  * @param sb            superblock
    383  * @param count         number of mounts
     437 * @param sb    Superblock
     438 * @param count Number of mounts
     439 *
    384440 */
    385441void ext4_superblock_set_mount_count(ext4_superblock_t *sb, uint16_t count)
     
    390446/** Get maximum number of mount from last filesystem check.
    391447 *
    392  * @param sb            superblock
    393  * @return                      maximum number of mounts
     448 * @param sb Superblock
     449 *
     450 * @return Maximum number of mounts
     451 *
    394452 */
    395453uint16_t ext4_superblock_get_max_mount_count(ext4_superblock_t *sb)
     
    400458/** Set maximum number of mount from last filesystem check.
    401459 *
    402  * @param sb            superblock
    403  * @param count         maximum number of mounts
     460 * @param sb    Superblock
     461 * @param count Maximum number of mounts
     462 *
    404463 */
    405464void ext4_superblock_set_max_mount_count(ext4_superblock_t *sb, uint16_t count)
     
    410469/** Get superblock magic value.
    411470 *
    412  * @param sb            superblock
    413  * @return                      magic value
     471 * @param sb Superblock
     472 *
     473 * @return Magic value
     474 *
    414475 */
    415476uint16_t ext4_superblock_get_magic(ext4_superblock_t *sb)
     
    420481/** Set superblock magic value.
    421482 *
    422  * @param sb            superblock
    423  * @param                       magic value
     483 * @param sb    Superblock
     484 * @param magic Magic value
     485 *
    424486 */
    425487void ext4_superblock_set_magic(ext4_superblock_t *sb, uint16_t magic)
     
    430492/** Get filesystem state.
    431493 *
    432  * @param sb            superblock
    433  * @return                      filesystem state
     494 * @param sb Superblock
     495 *
     496 * @return Filesystem state
     497 *
    434498 */
    435499uint16_t ext4_superblock_get_state(ext4_superblock_t *sb)
     
    440504/** Set filesystem state.
    441505 *
    442  * @param sb            superblock
    443  * @param state         filesystem state
     506 * @param sb    Superblock
     507 * @param state Filesystem state
     508 *
    444509 */
    445510void ext4_superblock_set_state(ext4_superblock_t *sb, uint16_t state)
     
    450515/** Get behavior code when errors detected.
    451516 *
    452  * @param sb            superblock
    453  * @return                      behavior code
     517 * @param sb Superblock
     518 *
     519 * @return Behavior code
     520 *
    454521 */
    455522uint16_t ext4_superblock_get_errors(ext4_superblock_t *sb)
     
    460527/** Set behavior code when errors detected.
    461528 *
    462  * @param sb            superblock
    463  * @param errors        behavior code
     529 * @param sb     Superblock
     530 * @param errors Behavior code
     531 *
    464532 */
    465533void ext4_superblock_set_errors(ext4_superblock_t *sb, uint16_t errors)
     
    470538/** Get minor revision level of the filesystem.
    471539 *
    472  * @param sb            superblock
    473  * @return                      minor revision level
     540 * @param sb Superblock
     541 *
     542 * @return Minor revision level
     543 *
    474544 */
    475545uint16_t ext4_superblock_get_minor_rev_level(ext4_superblock_t *sb)
     
    480550/** Set minor revision level of the filesystem.
    481551 *
    482  * @param sb            superblock
    483  * @param level         minor revision level
     552 * @param sb    Superblock
     553 * @param level Minor revision level
     554 *
    484555 */
    485556void ext4_superblock_set_minor_rev_level(ext4_superblock_t *sb, uint16_t level)
     
    490561/** Get time of the last filesystem check.
    491562 *
    492  * @param sb            superblock
    493  * @return                      time of the last check (POSIX)
     563 * @param sb Superblock
     564 *
     565 * @return Time of the last check (POSIX)
     566 *
    494567 */
    495568uint32_t ext4_superblock_get_last_check_time(ext4_superblock_t *sb)
     
    500573/** Set time of the last filesystem check.
    501574 *
    502  * @param sb            superblock
    503  * @param time          time of the last check (POSIX)
     575 * @param sb   Superblock
     576 * @param time Time of the last check (POSIX)
     577 *
    504578 */
    505579void ext4_superblock_set_last_check_time(ext4_superblock_t *sb, uint32_t time)
     
    510584/** Get maximum time interval between two filesystem checks.
    511585 *
    512  * @param sb            superblock
    513  * @return                      time interval between two check (POSIX)
    514  */
    515 uint32_t ext4_superblock_get_check_interval(ext4_superblock_t *sb){
     586 * @param sb Superblock
     587 *
     588 * @return Time interval between two check (POSIX)
     589 *
     590 */
     591uint32_t ext4_superblock_get_check_interval(ext4_superblock_t *sb)
     592{
    516593        return uint32_t_le2host(sb->check_interval);
    517594}
     
    519596/** Set maximum time interval between two filesystem checks.
    520597 *
    521  * @param sb                    superblock
    522  * @param interval              time interval between two check (POSIX)
     598 * @param sb       Superblock
     599 * @param interval Time interval between two check (POSIX)
     600 *
    523601 */
    524602void ext4_superblock_set_check_interval(ext4_superblock_t *sb, uint32_t interval)
     
    529607/** Get operation system identifier, on which the filesystem was created.
    530608 *
    531  * @param sb            superblock
    532  * @return                      operation system identifier
     609 * @param sb Superblock
     610 *
     611 * @return Operation system identifier
     612 *
    533613 */
    534614uint32_t ext4_superblock_get_creator_os(ext4_superblock_t *sb)
     
    539619/** Set operation system identifier, on which the filesystem was created.
    540620 *
    541  * @param sb            superblock
    542  * @param os            operation system identifier
     621 * @param sb Superblock
     622 * @param os Operation system identifier
     623 *
    543624 */
    544625void ext4_superblock_set_creator_os(ext4_superblock_t *sb, uint32_t os)
     
    549630/** Get revision level of the filesystem.
    550631 *
    551  * @param sb            superblock
    552  * @return                      revision level
     632 * @param sb Superblock
     633 *
     634 * @return Revision level
     635 *
    553636 */
    554637uint32_t ext4_superblock_get_rev_level(ext4_superblock_t *sb)
     
    559642/** Set revision level of the filesystem.
    560643 *
    561  * @param sb            superblock
    562  * @param level         revision level
     644 * @param sb    Superblock
     645 * @param level Revision level
     646 *
    563647 */
    564648void ext4_superblock_set_rev_level(ext4_superblock_t *sb, uint32_t level)
     
    569653/** Get default user id for reserved blocks.
    570654 *
    571  * @param sb            superblock
    572  * @return                      default user id for reserved blocks.
     655 * @param sb Superblock
     656 *
     657 * @return Default user id for reserved blocks.
     658 *
    573659 */
    574660uint16_t ext4_superblock_get_def_resuid(ext4_superblock_t *sb)
     
    579665/** Set default user id for reserved blocks.
    580666 *
    581  * @param sb            superblock
    582  * @param uid           default user id for reserved blocks.
     667 * @param sb  Superblock
     668 * @param uid Default user id for reserved blocks.
     669 *
    583670 */
    584671void ext4_superblock_set_def_resuid(ext4_superblock_t *sb, uint16_t uid)
     
    589676/** Get default group id for reserved blocks.
    590677 *
    591  * @param sb            superblock
    592  * @return                      default group id for reserved blocks.
     678 * @param sb Superblock
     679 *
     680 * @return Default group id for reserved blocks.
     681 *
    593682 */
    594683uint16_t ext4_superblock_get_def_resgid(ext4_superblock_t *sb)
     
    599688/** Set default group id for reserved blocks.
    600689 *
    601  * @param sb            superblock
    602  * @param gid           default group id for reserved blocks.
     690 * @param sb  Superblock
     691 * @param gid Default group id for reserved blocks.
     692 *
    603693 */
    604694void ext4_superblock_set_def_resgid(ext4_superblock_t *sb, uint16_t gid)
     
    609699/** Get index of the first i-node, which can be used for allocation.
    610700 *
    611  * @param sb            superblock
    612  * @return                      i-node index
     701 * @param sb Superblock
     702 *
     703 * @return I-node index
     704 *
    613705 */
    614706uint32_t ext4_superblock_get_first_inode(ext4_superblock_t *sb)
     
    619711/** Set index of the first i-node, which can be used for allocation.
    620712 *
    621  * @param sb                    superblock
    622  * @param first_inode   i-node index
    623  */
    624 void ext4_superblock_set_first_inode(ext4_superblock_t *sb, uint32_t first_inode)
     713 * @param sb          Superblock
     714 * @param first_inode I-node index
     715 *
     716 */
     717void ext4_superblock_set_first_inode(ext4_superblock_t *sb,
     718    uint32_t first_inode)
    625719{
    626720        sb->first_inode = host2uint32_t_le(first_inode);
     
    631725 * For the oldest revision return constant number.
    632726 *
    633  * @param sb                    superblock
    634  * @return                              size of i-node structure
     727 * @param sb Superblock
     728 *
     729 * @return Size of i-node structure
     730 *
    635731 */
    636732uint16_t ext4_superblock_get_inode_size(ext4_superblock_t *sb)
    637733{
    638         if (ext4_superblock_get_rev_level(sb) == 0) {
     734        if (ext4_superblock_get_rev_level(sb) == 0)
    639735                return EXT4_REV0_INODE_SIZE;
    640         }
     736       
    641737        return uint16_t_le2host(sb->inode_size);
    642738}
     
    644740/** Set size of i-node structure.
    645741 *
    646  * @param sb                    superblock
    647  * @param size                  size of i-node structure
     742 * @param sb   Superblock
     743 * @param size Size of i-node structure
     744 *
    648745 */
    649746void ext4_superblock_set_inode_size(ext4_superblock_t *sb, uint16_t size)
     
    654751/** Get index of block group, where superblock copy is located.
    655752 *
    656  * @param sb                    superblock
    657  * @return                              block group index
     753 * @param sb Superblock
     754 *
     755 * @return Block group index
     756 *
    658757 */
    659758uint16_t ext4_superblock_get_block_group_index(ext4_superblock_t *sb)
     
    664763/** Set index of block group, where superblock copy is located.
    665764 *
    666  * @param sb                    superblock
    667  * @param bgid                  block group index
     765 * @param sb   Superblock
     766 * @param bgid Block group index
     767 *
    668768 */
    669769void ext4_superblock_set_block_group_index(ext4_superblock_t *sb, uint16_t bgid)
     
    674774/** Get compatible features supported by the filesystem.
    675775 *
    676  * @param sb            superblock
    677  * @return                      compatible features bitmap
     776 * @param sb Superblock
     777 *
     778 * @return Compatible features bitmap
     779 *
    678780 */
    679781uint32_t ext4_superblock_get_features_compatible(ext4_superblock_t *sb)
     
    684786/** Set compatible features supported by the filesystem.
    685787 *
    686  * @param sb                    superblock
    687  * @param features              compatible features bitmap
    688  */
    689 void ext4_superblock_set_features_compatible(ext4_superblock_t *sb, uint32_t features)
     788 * @param sb       Superblock
     789 * @param features Compatible features bitmap
     790 *
     791 */
     792void ext4_superblock_set_features_compatible(ext4_superblock_t *sb,
     793    uint32_t features)
    690794{
    691795        sb->features_compatible = host2uint32_t_le(features);
     
    694798/** Get incompatible features supported by the filesystem.
    695799 *
    696  * @param sb            superblock
    697  * @return                      incompatible features bitmap
     800 * @param sb Superblock
     801 *
     802 * @return Incompatible features bitmap
     803 *
    698804 */
    699805uint32_t ext4_superblock_get_features_incompatible(ext4_superblock_t *sb)
     
    704810/** Set incompatible features supported by the filesystem.
    705811 *
    706  * @param sb                    superblock
    707  * @param features              incompatible features bitmap
    708  */
    709 void ext4_superblock_set_features_incompatible(ext4_superblock_t *sb, uint32_t features)
     812 * @param sb       Superblock
     813 * @param features Incompatible features bitmap
     814 *
     815 */
     816void ext4_superblock_set_features_incompatible(ext4_superblock_t *sb,
     817    uint32_t features)
    710818{
    711819        sb->features_incompatible = host2uint32_t_le(features);
     
    714822/** Get compatible features supported by the filesystem.
    715823 *
    716  * @param sb            superblock
    717  * @return                      read-only compatible features bitmap
     824 * @param sb Superblock
     825 *
     826 * @return Read-only compatible features bitmap
     827 *
    718828 */
    719829uint32_t ext4_superblock_get_features_read_only(ext4_superblock_t *sb)
     
    724834/** Set compatible features supported by the filesystem.
    725835 *
    726  * @param sb                    superblock
    727  * @param feature               read-only compatible features bitmap
    728  */
    729 void ext4_superblock_set_features_read_only(ext4_superblock_t *sb, uint32_t features)
     836 * @param sb      Superblock
     837 * @param feature Read-only compatible features bitmap
     838 *
     839 */
     840void ext4_superblock_set_features_read_only(ext4_superblock_t *sb,
     841    uint32_t features)
    730842{
    731843        sb->features_read_only = host2uint32_t_le(features);
     
    734846/** Get UUID of the filesystem.
    735847 *
    736  * @param sb            superblock
    737  * @return                      pointer to UUID array
    738  */
    739 const uint8_t * ext4_superblock_get_uuid(ext4_superblock_t *sb)
     848 * @param sb superblock
     849 *
     850 * @return Pointer to UUID array
     851 *
     852 */
     853const uint8_t *ext4_superblock_get_uuid(ext4_superblock_t *sb)
    740854{
    741855        return sb->uuid;
     
    744858/** Set UUID of the filesystem.
    745859 *
    746  * @param sb            superblock
    747  * @param uuid          pointer to UUID array
     860 * @param sb   Superblock
     861 * @param uuid Pointer to UUID array
     862 *
    748863 */
    749864void ext4_superblock_set_uuid(ext4_superblock_t *sb, const uint8_t *uuid)
     
    754869/** Get name of the filesystem volume.
    755870 *
    756  * @param sb            superblock
    757  * @return                      name of the volume
    758  */
    759 const char * ext4_superblock_get_volume_name(ext4_superblock_t *sb)
     871 * @param sb Superblock
     872 *
     873 * @return Name of the volume
     874 *
     875 */
     876const char *ext4_superblock_get_volume_name(ext4_superblock_t *sb)
    760877{
    761878        return sb->volume_name;
     
    764881/** Set name of the filesystem volume.
    765882 *
    766  * @param sb            superblock
    767  * @param name          new name of the volume
     883 * @param sb   Superblock
     884 * @param name New name of the volume
    768885 */
    769886void ext4_superblock_set_volume_name(ext4_superblock_t *sb, const char *name)
     
    774891/** Get name of the directory, where this filesystem was mounted at last.
    775892 *
    776  * @param sb            superblock
    777  * @return                      directory name
    778  */
    779 const char * ext4_superblock_get_last_mounted(ext4_superblock_t *sb)
     893 * @param sb Superblock
     894 *
     895 * @return Directory name
     896 *
     897 */
     898const char *ext4_superblock_get_last_mounted(ext4_superblock_t *sb)
    780899{
    781900        return sb->last_mounted;
     
    784903/** Set name of the directory, where this filesystem was mounted at last.
    785904 *
    786  * @param sb            superblock
    787  * @param last          directory name
     905 * @param sb   Superblock
     906 * @param last Directory name
     907 *
    788908 */
    789909void ext4_superblock_set_last_mounted(ext4_superblock_t *sb, const char *last)
     
    796916 * Orphans are stored in linked list.
    797917 *
    798  * @param sb            superblock
    799  * @return                      last orphaned i-node index
     918 * @param sb Superblock
     919 *
     920 * @return Last orphaned i-node index
     921 *
    800922 */
    801923uint32_t ext4_superblock_get_last_orphan(ext4_superblock_t *sb)
     
    808930 * Orphans are stored in linked list.
    809931 *
    810  * @param sb                    superblock
    811  * @param last_orphan   last orphaned i-node index
    812  */
    813 void ext4_superblock_set_last_orphan(ext4_superblock_t *sb, uint32_t last_orphan)
     932 * @param sb          Superblock
     933 * @param last_orphan Last orphaned i-node index
     934 *
     935 */
     936void ext4_superblock_set_last_orphan(ext4_superblock_t *sb,
     937    uint32_t last_orphan)
    814938{
    815939        sb->last_orphan = host2uint32_t_le(last_orphan);
     
    818942/** Get hash seed for directory index hash function.
    819943 *
    820  * @param sb            superblock
    821  * @return                      hash seed pointer
    822  */
    823 const uint32_t * ext4_superblock_get_hash_seed(ext4_superblock_t *sb)
     944 * @param sb Superblock
     945 *
     946 * @return Hash seed pointer
     947 *
     948 */
     949const uint32_t *ext4_superblock_get_hash_seed(ext4_superblock_t *sb)
    824950{
    825951        return sb->hash_seed;
     
    828954/** Set hash seed for directory index hash function.
    829955 *
    830  * @param sb            superblock
    831  * @param seed          hash seed pointer
     956 * @param sb   Superblock
     957 * @param seed Hash seed pointer
     958 *
    832959 */
    833960void ext4_superblock_set_hash_seed(ext4_superblock_t *sb, const uint32_t *seed)
     
    838965/** Get default version of the hash algorithm version for directory index.
    839966 *
    840  * @param sb            superblock
    841  * @return                      default hash version
     967 * @param sb Superblock
     968 *
     969 * @return Default hash version
     970 *
    842971 */
    843972uint8_t ext4_superblock_get_default_hash_version(ext4_superblock_t *sb)
     
    848977/** Set default version of the hash algorithm version for directory index.
    849978 *
    850  * @param sb            superblock
    851  * @param version       default hash version
    852  */
    853 void ext4_superblock_set_default_hash_version(ext4_superblock_t *sb, uint8_t version)
     979 * @param sb      Superblock
     980 * @param version Default hash version
     981 *
     982 */
     983void ext4_superblock_set_default_hash_version(ext4_superblock_t *sb,
     984    uint8_t version)
    854985{
    855986        sb->default_hash_version = version;
     
    860991 * Output value is checked for minimal size.
    861992 *
    862  * @param sb            superblock
    863  * @return                      size of block group descriptor
     993 * @param sb Superblock
     994 *
     995 * @return Size of block group descriptor
     996 *
    864997 */
    865998uint16_t ext4_superblock_get_desc_size(ext4_superblock_t *sb)
    866999{
    8671000        uint16_t size = uint16_t_le2host(sb->desc_size);
    868 
    869         if (size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
     1001       
     1002        if (size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
    8701003                size = EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE;
    871         }
    872 
     1004       
    8731005        return size;
    8741006}
     
    8781010 * Input value is checked for minimal size.
    8791011 *
    880  * @param sb            superblock
    881  * @param size          size of block group descriptor
     1012 * @param sb   Superblock
     1013 * @param size Size of block group descriptor
     1014 *
    8821015 */
    8831016void ext4_superblock_set_desc_size(ext4_superblock_t *sb, uint16_t size)
    8841017{
    885         if (size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
    886                 sb->desc_size = host2uint16_t_le(EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE);
    887         }
    888 
     1018        if (size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
     1019                sb->desc_size =
     1020                    host2uint16_t_le(EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE);
     1021       
    8891022        sb->desc_size = host2uint16_t_le(size);
    8901023}
     
    8921025/** Get superblock flags.
    8931026 *
    894  * @param sb            superblock
    895  * @return                      flags from the superblock
     1027 * @param sb Superblock
     1028 *
     1029 * @return Flags from the superblock
     1030 *
    8961031 */
    8971032uint32_t ext4_superblock_get_flags(ext4_superblock_t *sb)
     
    9021037/** Set superblock flags.
    9031038 *
    904  * @param sb            superblock
    905  * @param flags         flags for the superblock
     1039 * @param sb    Superblock
     1040 * @param flags Flags for the superblock
     1041 *
    9061042 */
    9071043void ext4_superblock_set_flags(ext4_superblock_t *sb, uint32_t flags)
     
    9161052/** Check if superblock has specified flag.
    9171053 *
    918  * @param sb                    superblock
    919  * @param flag                  flag to be checked
    920  * @return                              true, if superblock has the flag
     1054 * @param sb   Superblock
     1055 * @param flag Flag to be checked
     1056 *
     1057 * @return True, if superblock has the flag
     1058 *
    9211059 */
    9221060bool ext4_superblock_has_flag(ext4_superblock_t *sb, uint32_t flag)
    9231061{
    924         if (ext4_superblock_get_flags(sb) & flag) {
     1062        if (ext4_superblock_get_flags(sb) & flag)
    9251063                return true;
    926         }
     1064       
    9271065        return false;
    9281066}
     
    9301068/** Check if filesystem supports compatible feature.
    9311069 *
    932  * @param sb                    superblock
    933  * @param feature               feature to be checked
    934  * @return                              true, if filesystem supports the feature
    935  */
    936 bool ext4_superblock_has_feature_compatible(ext4_superblock_t *sb, uint32_t feature)
    937 {
    938         if (ext4_superblock_get_features_compatible(sb) & feature) {
     1070 * @param sb      Superblock
     1071 * @param feature Feature to be checked
     1072 *
     1073 * @return True, if filesystem supports the feature
     1074 *
     1075 */
     1076bool ext4_superblock_has_feature_compatible(ext4_superblock_t *sb,
     1077    uint32_t feature)
     1078{
     1079        if (ext4_superblock_get_features_compatible(sb) & feature)
    9391080                return true;
    940         }
     1081       
    9411082        return false;
    9421083}
     
    9441085/** Check if filesystem supports incompatible feature.
    9451086 *
    946  * @param sb                    superblock
    947  * @param feature               feature to be checked
    948  * @return                              true, if filesystem supports the feature
    949  */
    950 bool ext4_superblock_has_feature_incompatible(ext4_superblock_t *sb, uint32_t feature)
    951 {
    952         if (ext4_superblock_get_features_incompatible(sb) & feature) {
     1087 * @param sb      Superblock
     1088 * @param feature Feature to be checked
     1089 *
     1090 * @return True, if filesystem supports the feature
     1091 *
     1092 */
     1093bool ext4_superblock_has_feature_incompatible(ext4_superblock_t *sb,
     1094    uint32_t feature)
     1095{
     1096        if (ext4_superblock_get_features_incompatible(sb) & feature)
    9531097                return true;
    954         }
     1098       
    9551099        return false;
    9561100}
     
    9581102/** Check if filesystem supports read-only compatible feature.
    9591103 *
    960  * @param sb                    superblock
    961  * @param feature               feature to be checked
    962  * @return                              true, if filesystem supports the feature
    963  */
    964 bool ext4_superblock_has_feature_read_only(ext4_superblock_t *sb, uint32_t feature)
    965 {
    966         if (ext4_superblock_get_features_read_only(sb) & feature) {
     1104 * @param sb      Superblock
     1105 * @param feature Feature to be checked
     1106 *
     1107 * @return True, if filesystem supports the feature
     1108 *
     1109 */
     1110bool ext4_superblock_has_feature_read_only(ext4_superblock_t *sb,
     1111    uint32_t feature)
     1112{
     1113        if (ext4_superblock_get_features_read_only(sb) & feature)
    9671114                return true;
    968         }
     1115       
    9691116        return false;
    9701117}
     
    9721119/** Read superblock directly from block device.
    9731120 *
    974  * @param service_id            block device identifier
    975  * @param sb                            output pointer to memory structure
    976  * @return                                      error code.
    977  */
    978 int ext4_superblock_read_direct(service_id_t service_id,
    979     ext4_superblock_t **sb)
    980 {
    981         int rc;
    982 
     1121 * @param service_id Block device identifier
     1122 * @param sb         Output pointer to memory structure
     1123 *
     1124 * @return Eerror code.
     1125 *
     1126 */
     1127int ext4_superblock_read_direct(service_id_t service_id, ext4_superblock_t **sb)
     1128{
    9831129        /* Allocated memory for superblock structure */
    9841130        void *data = malloc(EXT4_SUPERBLOCK_SIZE);
    985         if (data == NULL) {
     1131        if (data == NULL)
    9861132                return ENOMEM;
    987         }
    988 
     1133       
    9891134        /* Read data from block device */
    990         rc = block_read_bytes_direct(service_id, EXT4_SUPERBLOCK_OFFSET,
     1135        int rc = block_read_bytes_direct(service_id, EXT4_SUPERBLOCK_OFFSET,
    9911136            EXT4_SUPERBLOCK_SIZE, data);
    992 
     1137       
    9931138        if (rc != EOK) {
    9941139                free(data);
    9951140                return rc;
    9961141        }
    997 
     1142       
    9981143        /* Set output value */
    9991144        (*sb) = data;
    1000 
     1145       
    10011146        return EOK;
    10021147}
     
    10041149/** Write superblock structure directly to block device.
    10051150 *
    1006  * @param service_id            block device identifier
    1007  * @param sb                            superblock to be written
    1008  * @return                                      error code
    1009  */
    1010 int ext4_superblock_write_direct(service_id_t service_id,
    1011                 ext4_superblock_t *sb)
    1012 {
    1013         int rc;
     1151 * @param service_id Block device identifier
     1152 * @param sb         Superblock to be written
     1153 *
     1154 * @return Error code
     1155 *
     1156 */
     1157int ext4_superblock_write_direct(service_id_t service_id, ext4_superblock_t *sb)
     1158{
     1159        /* Load physical block size from block device */
    10141160        size_t phys_block_size;
    1015 
    1016         /* Load physical block size from block device */
    1017         rc = block_get_bsize(service_id, &phys_block_size);
    1018         if (rc != EOK) {
     1161        int rc = block_get_bsize(service_id, &phys_block_size);
     1162        if (rc != EOK)
    10191163                return rc;
    1020         }
    1021 
     1164       
    10221165        /* Compute address of the first block */
    10231166        uint64_t first_block = EXT4_SUPERBLOCK_OFFSET / phys_block_size;
     1167       
    10241168        /* Compute number of block to write */
    10251169        size_t block_count = EXT4_SUPERBLOCK_SIZE / phys_block_size;
    1026 
     1170       
    10271171        /* Check alignment */
    1028         if (EXT4_SUPERBLOCK_SIZE % phys_block_size) {
     1172        if (EXT4_SUPERBLOCK_SIZE % phys_block_size)
    10291173                block_count++;
    1030         }
    1031 
     1174       
    10321175        /* Write data */
    10331176        return block_write_direct(service_id, first_block, block_count, sb);
    1034 
    10351177}
    10361178
     
    10401182 * Checks are described by one-line comments in the code.
    10411183 *
    1042  * @param sb            superblock to check
    1043  * @return                      error code
     1184 * @param sb Superblock to check
     1185 *
     1186 * @return Error code
     1187 *
    10441188 */
    10451189int ext4_superblock_check_sanity(ext4_superblock_t *sb)
    10461190{
    1047         if (ext4_superblock_get_magic(sb) != EXT4_SUPERBLOCK_MAGIC) {
     1191        if (ext4_superblock_get_magic(sb) != EXT4_SUPERBLOCK_MAGIC)
    10481192                return ENOTSUP;
    1049         }
    1050 
    1051         if (ext4_superblock_get_inodes_count(sb) == 0) {
     1193       
     1194        if (ext4_superblock_get_inodes_count(sb) == 0)
    10521195                return ENOTSUP;
    1053         }
    1054 
    1055         if (ext4_superblock_get_blocks_count(sb) == 0) {
     1196       
     1197        if (ext4_superblock_get_blocks_count(sb) == 0)
    10561198                return ENOTSUP;
    1057         }
    1058 
    1059         if (ext4_superblock_get_blocks_per_group(sb) == 0) {
     1199       
     1200        if (ext4_superblock_get_blocks_per_group(sb) == 0)
    10601201                return ENOTSUP;
    1061         }
    1062 
    1063         if (ext4_superblock_get_inodes_per_group(sb) == 0) {
     1202       
     1203        if (ext4_superblock_get_inodes_per_group(sb) == 0)
    10641204                return ENOTSUP;
    1065         }
    1066 
    1067         if (ext4_superblock_get_inode_size(sb) < 128) {
     1205       
     1206        if (ext4_superblock_get_inode_size(sb) < 128)
    10681207                return ENOTSUP;
    1069         }
    1070 
    1071         if (ext4_superblock_get_first_inode(sb) < 11) {
     1208       
     1209        if (ext4_superblock_get_first_inode(sb) < 11)
    10721210                return ENOTSUP;
    1073         }
    1074 
    1075         if (ext4_superblock_get_desc_size(sb) < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
     1211       
     1212        if (ext4_superblock_get_desc_size(sb) <
     1213            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
    10761214                return ENOTSUP;
    1077         }
    1078 
    1079         if (ext4_superblock_get_desc_size(sb) > EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE) {
     1215       
     1216        if (ext4_superblock_get_desc_size(sb) >
     1217            EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE)
    10801218                return ENOTSUP;
    1081         }
    1082 
     1219       
    10831220        return EOK;
    10841221}
     
    10861223/** Compute number of block groups in the filesystem.
    10871224 *
    1088  * @param sb            superblock
    1089  * @return                      number of block groups
     1225 * @param sb Superblock
     1226 *
     1227 * @return Number of block groups
     1228 *
    10901229 */
    10911230uint32_t ext4_superblock_get_block_group_count(ext4_superblock_t *sb)
     
    10931232        uint64_t blocks_count = ext4_superblock_get_blocks_count(sb);
    10941233        uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
    1095 
     1234       
    10961235        uint32_t block_groups_count = blocks_count / blocks_per_group;
    1097 
    1098         if (blocks_count % blocks_per_group) {
     1236       
     1237        if (blocks_count % blocks_per_group)
    10991238                block_groups_count++;
    1100         }
    1101 
     1239       
    11021240        return block_groups_count;
    1103 
    11041241}
    11051242
    11061243/** Compute number of blocks in specified block group.
    11071244 *
    1108  * @param sb                    superblock
    1109  * @param bgid                  block group index
    1110  * @return                              number of blocks
     1245 * @param sb   Superblock
     1246 * @param bgid Block group index
     1247 *
     1248 * @return Number of blocks
     1249 *
    11111250 */
    11121251uint32_t ext4_superblock_get_blocks_in_group(ext4_superblock_t *sb, uint32_t bgid)
    11131252{
    1114         uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
    1115         uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
    1116         uint64_t total_blocks = ext4_superblock_get_blocks_count(sb);
    1117 
    1118         if (bgid < block_group_count - 1) {
     1253        uint32_t block_group_count =
     1254            ext4_superblock_get_block_group_count(sb);
     1255        uint32_t blocks_per_group =
     1256            ext4_superblock_get_blocks_per_group(sb);
     1257        uint64_t total_blocks =
     1258            ext4_superblock_get_blocks_count(sb);
     1259       
     1260        if (bgid < block_group_count - 1)
    11191261                return blocks_per_group;
    1120         } else {
     1262        else
    11211263                return (total_blocks - ((block_group_count - 1) * blocks_per_group));
    1122         }
    1123 
    11241264}
    11251265
    11261266/** Compute number of i-nodes in specified block group.
    11271267 *
    1128  * @param sb            superblock
    1129  * @param bgid          block group index
    1130  * @return                      number of i-nodes
     1268 * @param sb   Superblock
     1269 * @param bgid Block group index
     1270 *
     1271 * @return Number of i-nodes
     1272 *
    11311273 */
    11321274uint32_t ext4_superblock_get_inodes_in_group(ext4_superblock_t *sb, uint32_t bgid)
    11331275{
    1134         uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
    1135         uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
    1136         uint32_t total_inodes = ext4_superblock_get_inodes_count(sb);
    1137 
    1138         if (bgid < block_group_count - 1) {
     1276        uint32_t block_group_count =
     1277            ext4_superblock_get_block_group_count(sb);
     1278        uint32_t inodes_per_group =
     1279            ext4_superblock_get_inodes_per_group(sb);
     1280        uint32_t total_inodes =
     1281            ext4_superblock_get_inodes_count(sb);
     1282       
     1283        if (bgid < block_group_count - 1)
    11391284                return inodes_per_group;
    1140         } else {
     1285        else
    11411286                return (total_inodes - ((block_group_count - 1) * inodes_per_group));
    1142         }
    1143 
    11441287}
    11451288
    11461289/**
    11471290 * @}
    1148  */ 
     1291 */
  • uspace/lib/ext4/libext4_superblock.h

    rb08e7970 r38542dc  
    3636#include <libblock.h>
    3737#include <sys/types.h>
    38 
    3938#include "libext4_types.h"
    4039
     
    4443extern void ext4_superblock_set_blocks_count(ext4_superblock_t *, uint64_t);
    4544extern uint64_t ext4_superblock_get_reserved_blocks_count(ext4_superblock_t *);
    46 extern void ext4_superblock_set_reserved_blocks_count(ext4_superblock_t *, uint64_t);
     45extern void ext4_superblock_set_reserved_blocks_count(ext4_superblock_t *,
     46    uint64_t);
    4747extern uint64_t ext4_superblock_get_free_blocks_count(ext4_superblock_t *);
    48 extern void ext4_superblock_set_free_blocks_count(ext4_superblock_t *, uint64_t);
     48extern void ext4_superblock_set_free_blocks_count(ext4_superblock_t *,
     49    uint64_t);
    4950extern uint32_t ext4_superblock_get_free_inodes_count(ext4_superblock_t *);
    50 extern void ext4_superblock_set_free_inodes_count(ext4_superblock_t *, uint32_t);
     51extern void ext4_superblock_set_free_inodes_count(ext4_superblock_t *,
     52    uint32_t);
    5153extern uint32_t ext4_superblock_get_first_data_block(ext4_superblock_t *);
    5254extern void ext4_superblock_set_first_data_block(ext4_superblock_t *, uint32_t);
     
    98100extern void ext4_superblock_set_inode_size(ext4_superblock_t *, uint16_t);
    99101extern uint16_t ext4_superblock_get_block_group_index(ext4_superblock_t *);
    100 extern void ext4_superblock_set_block_group_index(ext4_superblock_t *, uint16_t);
    101 extern uint32_t ext4_superblock_get_features_compatible(ext4_superblock_t *);
    102 extern void     ext4_superblock_set_features_compatible(ext4_superblock_t *, uint32_t);
    103 extern uint32_t ext4_superblock_get_features_incompatible(ext4_superblock_t *);
    104 extern void     ext4_superblock_set_features_incompatible(ext4_superblock_t *, uint32_t);
    105 extern uint32_t ext4_superblock_get_features_read_only(ext4_superblock_t *);
    106 extern void     ext4_superblock_set_features_read_only(ext4_superblock_t *, uint32_t);
     102extern void ext4_superblock_set_block_group_index(ext4_superblock_t *,
     103    uint16_t);
     104extern uint32_t ext4_superblock_get_features_compatible(ext4_superblock_t *);
     105extern void ext4_superblock_set_features_compatible(ext4_superblock_t *,
     106    uint32_t);
     107extern uint32_t ext4_superblock_get_features_incompatible(ext4_superblock_t *);
     108extern void ext4_superblock_set_features_incompatible(ext4_superblock_t *,
     109    uint32_t);
     110extern uint32_t ext4_superblock_get_features_read_only(ext4_superblock_t *);
     111extern void ext4_superblock_set_features_read_only(ext4_superblock_t *,
     112    uint32_t);
    107113
    108114extern const uint8_t * ext4_superblock_get_uuid(ext4_superblock_t *);
     
    113119extern void ext4_superblock_set_last_mounted(ext4_superblock_t *, const char *);
    114120
    115 /*
    116 uint32_t s_algorithm_usage_bitmap; // For compression
    117 uint8_t s_prealloc_blocks; // Number of blocks to try to preallocate
    118 uint8_t s_prealloc_dir_blocks; // Number to preallocate for dirs
    119 uint16_t s_reserved_gdt_blocks; // Per group desc for online growth
    120 uint8_t s_journal_uuid[16]; // UUID of journal superblock
    121 uint32_t s_journal_inum; // Inode number of journal file
    122 uint32_t s_journal_dev; // Device number of journal file
    123 */
    124121extern uint32_t ext4_superblock_get_last_orphan(ext4_superblock_t *);
    125122extern void ext4_superblock_set_last_orphan(ext4_superblock_t *, uint32_t);
    126123extern const uint32_t * ext4_superblock_get_hash_seed(ext4_superblock_t *);
    127 extern void ext4_superblock_set_hash_seed(ext4_superblock_t *, const uint32_t *);
     124extern void ext4_superblock_set_hash_seed(ext4_superblock_t *,
     125    const uint32_t *);
    128126extern uint8_t ext4_superblock_get_default_hash_version(ext4_superblock_t *);
    129 extern void ext4_superblock_set_default_hash_version(ext4_superblock_t *, uint8_t);
    130 /*
    131 uint8_t s_jnl_backup_type;
    132 */
     127extern void ext4_superblock_set_default_hash_version(ext4_superblock_t *,
     128    uint8_t);
    133129
    134130extern uint16_t ext4_superblock_get_desc_size(ext4_superblock_t *);
    135131extern void ext4_superblock_set_desc_size(ext4_superblock_t *, uint16_t);
    136132
    137 /*
    138 uint32_t s_default_mount_opts; // Default mount options
    139 uint32_t s_first_meta_bg; // First metablock block group
    140 uint32_t s_mkfs_time; // When the filesystem was created
    141 uint32_t s_jnl_blocks[17]; // Backup of the journal inode
    142 uint16_t s_min_extra_isize; // All inodes have at least # bytes
    143 uint16_t s_want_extra_isize; // New inodes should reserve # bytes
    144 */
    145133extern uint32_t ext4_superblock_get_flags(ext4_superblock_t *);
    146134extern void ext4_superblock_set_flags(ext4_superblock_t *, uint32_t);
    147 /*
    148 uint16_t s_raid_stride; // RAID stride
    149 uint16_t s_mmp_interval; // # seconds to wait in MMP checking
    150 uint64_t s_mmp_block; // Block for multi-mount protection
    151 uint32_t s_raid_stripe_width; // blocks on all data disks (N*stride)
    152 uint8_t s_log_groups_per_flex; // FLEX_BG group size
    153 uint8_t s_reserved_char_pad;
    154 uint16_t s_reserved_pad;
    155 uint64_t s_kbytes_written; // Number of lifetime kilobytes written
    156 uint32_t s_snapshot_inum; // Inode number of active snapshot
    157 uint32_t s_snapshot_id; // Sequential ID of active snapshot
    158 uint64_t s_snapshot_r_blocks_count; // reserved blocks for active snapshot's future use
    159 uint32_t s_snapshot_list; // inode number of the head of the on-disk snapshot list
    160 uint32_t s_error_count; // number of fs errors
    161 uint32_t s_first_error_time; // First time an error happened
    162 uint32_t s_first_error_ino; // Inode involved in first error
    163 uint64_t s_first_error_block; // block involved of first error
    164 uint8_t s_first_error_func[32]; // Function where the error happened
    165 uint32_t s_first_error_line; // Line number where error happened
    166 uint32_t s_last_error_time; // Most recent time of an error
    167 uint32_t s_last_error_ino; // Inode involved in last error
    168 uint32_t s_last_error_line; // Line number where error happened
    169 uint64_t s_last_error_block;     // block involved of last error
    170 uint8_t s_last_error_func[32];  // function where the error happened
    171 uint8_t s_mount_opts[64];
    172 */
    173135
    174136/* More complex superblock functions */
    175137extern bool ext4_superblock_has_flag(ext4_superblock_t *, uint32_t);
    176 extern bool ext4_superblock_has_feature_compatible(ext4_superblock_t *, uint32_t);
    177 extern bool ext4_superblock_has_feature_incompatible(ext4_superblock_t *, uint32_t);
    178 extern bool ext4_superblock_has_feature_read_only(ext4_superblock_t *, uint32_t);
     138extern bool ext4_superblock_has_feature_compatible(ext4_superblock_t *,
     139    uint32_t);
     140extern bool ext4_superblock_has_feature_incompatible(ext4_superblock_t *,
     141    uint32_t);
     142extern bool ext4_superblock_has_feature_read_only(ext4_superblock_t *,
     143    uint32_t);
    179144extern int ext4_superblock_read_direct(service_id_t, ext4_superblock_t **);
    180145extern int ext4_superblock_write_direct(service_id_t, ext4_superblock_t *);
     
    182147
    183148extern uint32_t ext4_superblock_get_block_group_count(ext4_superblock_t *);
    184 extern uint32_t ext4_superblock_get_blocks_in_group(ext4_superblock_t *, uint32_t);
    185 extern uint32_t ext4_superblock_get_inodes_in_group(ext4_superblock_t *, uint32_t);
     149extern uint32_t ext4_superblock_get_blocks_in_group(ext4_superblock_t *,
     150    uint32_t);
     151extern uint32_t ext4_superblock_get_inodes_in_group(ext4_superblock_t *,
     152    uint32_t);
    186153
    187154#endif
  • uspace/lib/ext4/libext4_types.h

    rb08e7970 r38542dc  
    2929/** @addtogroup libext4
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef LIBEXT4_LIBEXT4_TYPES_H_
     
    4040 */
    4141typedef struct ext4_superblock {
    42         uint32_t inodes_count; // Inodes count
    43         uint32_t blocks_count_lo; // Blocks count
    44         uint32_t reserved_blocks_count_lo; // Reserved blocks count
    45         uint32_t free_blocks_count_lo; // Free blocks count
    46         uint32_t free_inodes_count; // Free inodes count
    47         uint32_t first_data_block; // First Data Block
    48         uint32_t log_block_size; // Block size
    49         uint32_t log_frag_size; // Obsoleted fragment size
    50         uint32_t blocks_per_group; // Number of blocks per group
    51         uint32_t frags_per_group; // Obsoleted fragments per group
    52         uint32_t inodes_per_group; // Number of inodes per group
    53         uint32_t mount_time; // Mount time
    54         uint32_t write_time; // Write time
    55         uint16_t mount_count; // Mount count
    56         uint16_t max_mount_count; // Maximal mount count
    57         uint16_t magic; // Magic signature
    58         uint16_t state; // Filesystem state
    59         uint16_t errors; // Behaviour when detecting errors
    60         uint16_t minor_rev_level; // Minor revision level
    61         uint32_t last_check_time; // Time of last check
    62         uint32_t check_interval; // Maximum time between checks
    63         uint32_t creator_os; // Creator OS
    64         uint32_t rev_level; // Revision level
    65         uint16_t def_resuid; // Default uid for reserved blocks
    66         uint16_t def_resgid; // Default gid for reserved blocks
    67 
    68         // Fields for EXT4_DYNAMIC_REV superblocks only.
    69         uint32_t first_inode; // First non-reserved inode
    70         uint16_t inode_size; // Size of inode structure
    71         uint16_t block_group_index; // Block group index of this superblock
    72         uint32_t features_compatible; // Compatible feature set
    73         uint32_t features_incompatible; // Incompatible feature set
    74         uint32_t features_read_only; // Readonly-compatible feature set
    75         uint8_t uuid[16]; // 128-bit uuid for volume
    76         char volume_name[16]; // Volume name
    77         char last_mounted[64]; // Directory where last mounted
    78         uint32_t algorithm_usage_bitmap; // For compression
    79 
     42        uint32_t inodes_count;              /* I-nodes count */
     43        uint32_t blocks_count_lo;           /* Blocks count */
     44        uint32_t reserved_blocks_count_lo;  /* Reserved blocks count */
     45        uint32_t free_blocks_count_lo;      /* Free blocks count */
     46        uint32_t free_inodes_count;         /* Free inodes count */
     47        uint32_t first_data_block;          /* First Data Block */
     48        uint32_t log_block_size;            /* Block size */
     49        uint32_t log_frag_size;             /* Obsoleted fragment size */
     50        uint32_t blocks_per_group;          /* Number of blocks per group */
     51        uint32_t frags_per_group;           /* Obsoleted fragments per group */
     52        uint32_t inodes_per_group;          /* Number of inodes per group */
     53        uint32_t mount_time;                /* Mount time */
     54        uint32_t write_time;                /* Write time */
     55        uint16_t mount_count;               /* Mount count */
     56        uint16_t max_mount_count;           /* Maximal mount count */
     57        uint16_t magic;                     /* Magic signature */
     58        uint16_t state;                     /* File system state */
     59        uint16_t errors;                    /* Behaviour when detecting errors */
     60        uint16_t minor_rev_level;           /* Minor revision level */
     61        uint32_t last_check_time;           /* Time of last check */
     62        uint32_t check_interval;            /* Maximum time between checks */
     63        uint32_t creator_os;                /* Creator OS */
     64        uint32_t rev_level;                 /* Revision level */
     65        uint16_t def_resuid;                /* Default uid for reserved blocks */
     66        uint16_t def_resgid;                /* Default gid for reserved blocks */
     67       
     68        /* Fields for EXT4_DYNAMIC_REV superblocks only. */
     69        uint32_t first_inode;             /* First non-reserved inode */
     70        uint16_t inode_size;              /* Size of inode structure */
     71        uint16_t block_group_index;       /* Block group index of this superblock */
     72        uint32_t features_compatible;     /* Compatible feature set */
     73        uint32_t features_incompatible;   /* Incompatible feature set */
     74        uint32_t features_read_only;      /* Readonly-compatible feature set */
     75        uint8_t uuid[16];                 /* 128-bit uuid for volume */
     76        char volume_name[16];             /* Volume name */
     77        char last_mounted[64];            /* Directory where last mounted */
     78        uint32_t algorithm_usage_bitmap;  /* For compression */
     79       
    8080        /*
    8181         * Performance hints. Directory preallocation should only
    8282         * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
    8383         */
    84         uint8_t s_prealloc_blocks; // Number of blocks to try to preallocate
    85         uint8_t s_prealloc_dir_blocks; // Number to preallocate for dirs
    86         uint16_t s_reserved_gdt_blocks; // Per group desc for online growth
    87 
     84        uint8_t s_prealloc_blocks;       /* Number of blocks to try to preallocate */
     85        uint8_t s_prealloc_dir_blocks;   /* Number to preallocate for dirs */
     86        uint16_t s_reserved_gdt_blocks;  /* Per group desc for online growth */
     87       
    8888        /*
    8989         * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.
    9090         */
    91         uint8_t journal_uuid[16]; // UUID of journal superblock
    92         uint32_t journal_inode_number; // Inode number of journal file
    93         uint32_t journal_dev; // Device number of journal file
    94         uint32_t last_orphan; // Head of list of inodes to delete
    95         uint32_t hash_seed[4]; // HTREE hash seed
    96         uint8_t default_hash_version; // Default hash version to use
     91        uint8_t journal_uuid[16];       /* UUID of journal superblock */
     92        uint32_t journal_inode_number;  /* Inode number of journal file */
     93        uint32_t journal_dev;           /* Device number of journal file */
     94        uint32_t last_orphan;           /* Head of list of inodes to delete */
     95        uint32_t hash_seed[4];          /* HTREE hash seed */
     96        uint8_t default_hash_version;   /* Default hash version to use */
    9797        uint8_t journal_backup_type;
    98         uint16_t desc_size; // Size of group descriptor
    99         uint32_t default_mount_opts; // Default mount options
    100         uint32_t first_meta_bg; // First metablock block group
    101         uint32_t mkfs_time; // When the filesystem was created
    102         uint32_t journal_blocks[17]; // Backup of the journal inode
     98        uint16_t desc_size;             /* Size of group descriptor */
     99        uint32_t default_mount_opts;    /* Default mount options */
     100        uint32_t first_meta_bg;         /* First metablock block group */
     101        uint32_t mkfs_time;             /* When the filesystem was created */
     102        uint32_t journal_blocks[17];    /* Backup of the journal inode */
    103103
    104104        /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
    105         uint32_t blocks_count_hi; // Blocks count
    106         uint32_t reserved_blocks_count_hi; // Reserved blocks count
    107         uint32_t free_blocks_count_hi; // Free blocks count
    108         uint16_t min_extra_isize; // All inodes have at least # bytes
    109         uint16_t want_extra_isize; // New inodes should reserve # bytes
    110         uint32_t flags; // Miscellaneous flags
    111         uint16_t raid_stride; // RAID stride
    112         uint16_t mmp_interval; // # seconds to wait in MMP checking
    113         uint64_t mmp_block; // Block for multi-mount protection
    114         uint32_t raid_stripe_width; // blocks on all data disks (N*stride)
    115         uint8_t log_groups_per_flex; // FLEX_BG group size
     105        uint32_t blocks_count_hi;           /* Blocks count */
     106        uint32_t reserved_blocks_count_hi;  /* Reserved blocks count */
     107        uint32_t free_blocks_count_hi;      /* Free blocks count */
     108        uint16_t min_extra_isize;           /* All inodes have at least # bytes */
     109        uint16_t want_extra_isize;          /* New inodes should reserve # bytes */
     110        uint32_t flags;                     /* Miscellaneous flags */
     111        uint16_t raid_stride;               /* RAID stride */
     112        uint16_t mmp_interval;              /* # seconds to wait in MMP checking */
     113        uint64_t mmp_block;                 /* Block for multi-mount protection */
     114        uint32_t raid_stripe_width;         /* Blocks on all data disks (N * stride) */
     115        uint8_t log_groups_per_flex;        /* FLEX_BG group size */
    116116        uint8_t reserved_char_pad;
    117117        uint16_t reserved_pad;
    118         uint64_t kbytes_written; // Number of lifetime kilobytes written
    119         uint32_t snapshot_inum; // Inode number of active snapshot
    120         uint32_t snapshot_id; // Sequential ID of active snapshot
    121         uint64_t snapshot_r_blocks_count; /* reserved blocks for active snapshot's future use */
    122         uint32_t snapshot_list; // inode number of the head of the on-disk snapshot list
    123         uint32_t error_count; // number of fs errors
    124         uint32_t first_error_time; // First time an error happened
    125         uint32_t first_error_ino; // Inode involved in first error
    126         uint64_t first_error_block; // block involved of first error
    127         uint8_t first_error_func[32]; // Function where the error happened
    128         uint32_t first_error_line; // Line number where error happened
    129         uint32_t last_error_time; // Most recent time of an error
    130         uint32_t last_error_ino; // Inode involved in last error
    131         uint32_t last_error_line; // Line number where error happened
    132         uint64_t last_error_block;     // Block involved of last error
    133         uint8_t last_error_func[32];  // Function where the error happened
     118        uint64_t kbytes_written;            /* Number of lifetime kilobytes written */
     119        uint32_t snapshot_inum;             /* I-node number of active snapshot */
     120        uint32_t snapshot_id;               /* Sequential ID of active snapshot */
     121        uint64_t snapshot_r_blocks_count;   /* Reserved blocks for active snapshot's future use */
     122        uint32_t snapshot_list;             /* I-node number of the head of the on-disk snapshot list */
     123        uint32_t error_count;               /* Number of file system errors */
     124        uint32_t first_error_time;          /* First time an error happened */
     125        uint32_t first_error_ino;           /* I-node involved in first error */
     126        uint64_t first_error_block;         /* Block involved of first error */
     127        uint8_t first_error_func[32];       /* Function where the error happened */
     128        uint32_t first_error_line;          /* Line number where error happened */
     129        uint32_t last_error_time;           /* Most recent time of an error */
     130        uint32_t last_error_ino;            /* I-node involved in last error */
     131        uint32_t last_error_line;           /* Line number where error happened */
     132        uint64_t last_error_block;          /* Block involved of last error */
     133        uint8_t last_error_func[32];        /* Function where the error happened */
    134134        uint8_t mount_opts[64];
    135         uint32_t padding[112]; // Padding to the end of the block
     135        uint32_t padding[112];              /* Padding to the end of the block */
    136136} __attribute__((packed)) ext4_superblock_t;
    137137
    138138
    139 #define EXT4_SUPERBLOCK_MAGIC           0xEF53
    140 #define EXT4_SUPERBLOCK_SIZE            1024
    141 #define EXT4_SUPERBLOCK_OFFSET          1024
    142 
    143 #define EXT4_SUPERBLOCK_OS_LINUX        0
    144 #define EXT4_SUPERBLOCK_OS_HURD         1
     139#define EXT4_SUPERBLOCK_MAGIC   0xEF53
     140#define EXT4_SUPERBLOCK_SIZE    1024
     141#define EXT4_SUPERBLOCK_OFFSET  1024
     142
     143#define EXT4_SUPERBLOCK_OS_LINUX  0
     144#define EXT4_SUPERBLOCK_OS_HURD   1
    145145
    146146/*
    147147 * Misc. filesystem flags
    148148 */
    149 #define EXT4_SUPERBLOCK_FLAGS_SIGNED_HASH       0x0001  // Signed dirhash in use
    150 #define EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH     0x0002  // Unsigned dirhash in use
    151 #define EXT4_SUPERBLOCK_FLAGS_TEST_FILESYS      0x0004  // to test development code
     149#define EXT4_SUPERBLOCK_FLAGS_SIGNED_HASH    0x0001  /* Signed dirhash in use */
     150#define EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH  0x0002  /* Unsigned dirhash in use */
     151#define EXT4_SUPERBLOCK_FLAGS_TEST_FILESYS   0x0004  /* to test development code */
    152152
    153153/*
    154154 * Filesystem states
    155155 */
    156 #define EXT4_SUPERBLOCK_STATE_VALID_FS          0x0001  // Unmounted cleanly
    157 #define EXT4_SUPERBLOCK_STATE_ERROR_FS          0x0002  // Errors detected
    158 #define EXT4_SUPERBLOCK_STATE_ORPHAN_FS         0x0004  // Orphans being recovered
     156#define EXT4_SUPERBLOCK_STATE_VALID_FS   0x0001  /* Unmounted cleanly */
     157#define EXT4_SUPERBLOCK_STATE_ERROR_FS   0x0002  /* Errors detected */
     158#define EXT4_SUPERBLOCK_STATE_ORPHAN_FS  0x0004  /* Orphans being recovered */
    159159
    160160/*
    161161 * Behaviour when errors detected
    162162 */
    163 #define EXT4_SUPERBLOCK_ERRORS_CONTINUE         1 // Continue execution
    164 #define EXT4_SUPERBLOCK_ERRORS_RO                       2 // Remount fs read-only
    165 #define EXT4_SUPERBLOCK_ERRORS_PANIC            3 // Panic
    166 #define EXT4_SUPERBLOCK_ERRORS_DEFAULT          EXT4_ERRORS_CONTINUE
     163#define EXT4_SUPERBLOCK_ERRORS_CONTINUE  1  /* Continue execution */
     164#define EXT4_SUPERBLOCK_ERRORS_RO        2  /* Remount fs read-only */
     165#define EXT4_SUPERBLOCK_ERRORS_PANIC     3  /* Panic */
     166#define EXT4_SUPERBLOCK_ERRORS_DEFAULT   EXT4_ERRORS_CONTINUE
    167167
    168168/*
    169169 * Compatible features
    170170 */
    171 #define EXT4_FEATURE_COMPAT_DIR_PREALLOC        0x0001
    172 #define EXT4_FEATURE_COMPAT_IMAGIC_INODES       0x0002
    173 #define EXT4_FEATURE_COMPAT_HAS_JOURNAL         0x0004
    174 #define EXT4_FEATURE_COMPAT_EXT_ATTR            0x0008
    175 #define EXT4_FEATURE_COMPAT_RESIZE_INODE        0x0010
    176 #define EXT4_FEATURE_COMPAT_DIR_INDEX           0x0020
     171#define EXT4_FEATURE_COMPAT_DIR_PREALLOC   0x0001
     172#define EXT4_FEATURE_COMPAT_IMAGIC_INODES  0x0002
     173#define EXT4_FEATURE_COMPAT_HAS_JOURNAL    0x0004
     174#define EXT4_FEATURE_COMPAT_EXT_ATTR       0x0008
     175#define EXT4_FEATURE_COMPAT_RESIZE_INODE   0x0010
     176#define EXT4_FEATURE_COMPAT_DIR_INDEX      0x0020
    177177
    178178/*
    179179 * Read-only compatible features
    180180 */
    181 #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER     0x0001
    182 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE       0x0002
    183 #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR        0x0004
    184 #define EXT4_FEATURE_RO_COMPAT_HUGE_FILE        0x0008
    185 #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM         0x0010
    186 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK        0x0020
    187 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE      0x0040
     181#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER  0x0001
     182#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE    0x0002
     183#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR     0x0004
     184#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE     0x0008
     185#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM      0x0010
     186#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK     0x0020
     187#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE   0x0040
    188188
    189189/*
    190190 * Incompatible features
    191191 */
    192 #define EXT4_FEATURE_INCOMPAT_COMPRESSION       0x0001
    193 #define EXT4_FEATURE_INCOMPAT_FILETYPE          0x0002
    194 #define EXT4_FEATURE_INCOMPAT_RECOVER           0x0004 /* Needs recovery */
    195 #define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV       0x0008 /* Journal device */
    196 #define EXT4_FEATURE_INCOMPAT_META_BG           0x0010
    197 #define EXT4_FEATURE_INCOMPAT_EXTENTS           0x0040 /* extents support */
    198 #define EXT4_FEATURE_INCOMPAT_64BIT             0x0080
    199 #define EXT4_FEATURE_INCOMPAT_MMP               0x0100
    200 #define EXT4_FEATURE_INCOMPAT_FLEX_BG           0x0200
    201 #define EXT4_FEATURE_INCOMPAT_EA_INODE          0x0400 /* EA in inode */
    202 #define EXT4_FEATURE_INCOMPAT_DIRDATA           0x1000 /* data in dirent */
    203 
    204 #define EXT4_FEATURE_COMPAT_SUPP                (EXT4_FEATURE_COMPAT_DIR_INDEX)
    205 
    206 #define EXT4_FEATURE_INCOMPAT_SUPP      (EXT4_FEATURE_INCOMPAT_FILETYPE | \
    207                                          EXT4_FEATURE_INCOMPAT_EXTENTS | \
    208                                          EXT4_FEATURE_INCOMPAT_64BIT)
    209 
    210 #define EXT4_FEATURE_RO_COMPAT_SUPP     (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | \
    211                                                                                  EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \
    212                                                                                  EXT4_FEATURE_RO_COMPAT_HUGE_FILE | \
    213                                                                                  EXT4_FEATURE_RO_COMPAT_LARGE_FILE | \
    214                                                                                  EXT4_FEATURE_RO_COMPAT_GDT_CSUM | \
    215                                                                                  EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
    216 
    217 
    218 /*****************************************************************************/
     192#define EXT4_FEATURE_INCOMPAT_COMPRESSION  0x0001
     193#define EXT4_FEATURE_INCOMPAT_FILETYPE     0x0002
     194#define EXT4_FEATURE_INCOMPAT_RECOVER      0x0004  /* Needs recovery */
     195#define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV  0x0008  /* Journal device */
     196#define EXT4_FEATURE_INCOMPAT_META_BG      0x0010
     197#define EXT4_FEATURE_INCOMPAT_EXTENTS      0x0040  /* extents support */
     198#define EXT4_FEATURE_INCOMPAT_64BIT        0x0080
     199#define EXT4_FEATURE_INCOMPAT_MMP          0x0100
     200#define EXT4_FEATURE_INCOMPAT_FLEX_BG      0x0200
     201#define EXT4_FEATURE_INCOMPAT_EA_INODE     0x0400  /* EA in inode */
     202#define EXT4_FEATURE_INCOMPAT_DIRDATA      0x1000  /* data in dirent */
     203
     204#define EXT4_FEATURE_COMPAT_SUPP  (EXT4_FEATURE_COMPAT_DIR_INDEX)
     205
     206#define EXT4_FEATURE_INCOMPAT_SUPP \
     207        (EXT4_FEATURE_INCOMPAT_FILETYPE | \
     208        EXT4_FEATURE_INCOMPAT_EXTENTS | \
     209        EXT4_FEATURE_INCOMPAT_64BIT)
     210
     211#define EXT4_FEATURE_RO_COMPAT_SUPP \
     212        (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | \
     213        EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \
     214        EXT4_FEATURE_RO_COMPAT_HUGE_FILE | \
     215        EXT4_FEATURE_RO_COMPAT_LARGE_FILE | \
     216        EXT4_FEATURE_RO_COMPAT_GDT_CSUM | \
     217        EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
    219218
    220219typedef struct ext4_filesystem {
    221220        service_id_t device;
    222         ext4_superblock_t *     superblock;
     221        ext4_superblock_t *superblock;
    223222        aoff64_t inode_block_limits[4];
    224223        aoff64_t inode_blocks_per_level[4];
     
    226225
    227226
    228 /*****************************************************************************/
    229 
    230 #define EXT4_BLOCK_GROUP_INODE_UNINIT   0x0001 /* Inode table/bitmap not in use */
    231 #define EXT4_BLOCK_GROUP_BLOCK_UNINIT   0x0002 /* Block bitmap not in use */
    232 #define EXT4_BLOCK_GROUP_ITABLE_ZEROED  0x0004 /* On-disk itable initialized to zero */
     227#define EXT4_BLOCK_GROUP_INODE_UNINIT   0x0001  /* Inode table/bitmap not in use */
     228#define EXT4_BLOCK_GROUP_BLOCK_UNINIT   0x0002  /* Block bitmap not in use */
     229#define EXT4_BLOCK_GROUP_ITABLE_ZEROED  0x0004  /* On-disk itable initialized to zero */
    233230
    234231/*
     
    236233 */
    237234typedef struct ext4_block_group {
    238         uint32_t block_bitmap_lo; // Blocks bitmap block
    239         uint32_t inode_bitmap_lo; // Inodes bitmap block
    240         uint32_t inode_table_first_block_lo; // Inodes table block
    241         uint16_t free_blocks_count_lo; // Free blocks count
    242         uint16_t free_inodes_count_lo; // Free inodes count
    243         uint16_t used_dirs_count_lo; // Directories count
    244         uint16_t flags; // EXT4_BG_flags (INODE_UNINIT, etc)
    245         uint32_t reserved[2]; // Likely block/inode bitmap checksum
    246         uint16_t itable_unused_lo; // Unused inodes count
    247         uint16_t checksum; // crc16(sb_uuid+group+desc)
    248         /* -------------- */
    249         uint32_t block_bitmap_hi; // Blocks bitmap block MSB
    250         uint32_t inode_bitmap_hi; // Inodes bitmap block MSB
    251         uint32_t inode_table_first_block_hi; // Inodes table block MSB
    252         uint16_t free_blocks_count_hi; // Free blocks count MSB
    253         uint16_t free_inodes_count_hi; // Free inodes count MSB
    254         uint16_t used_dirs_count_hi; // Directories count MSB
    255         uint16_t itable_unused_hi;  // Unused inodes count MSB
    256         uint32_t reserved2[3]; // Padding
     235        uint32_t block_bitmap_lo;             /* Blocks bitmap block */
     236        uint32_t inode_bitmap_lo;             /* Inodes bitmap block */
     237        uint32_t inode_table_first_block_lo;  /* Inodes table block */
     238        uint16_t free_blocks_count_lo;        /* Free blocks count */
     239        uint16_t free_inodes_count_lo;        /* Free inodes count */
     240        uint16_t used_dirs_count_lo;          /* Directories count */
     241        uint16_t flags;                       /* EXT4_BG_flags (INODE_UNINIT, etc) */
     242        uint32_t reserved[2];                 /* Likely block/inode bitmap checksum */
     243        uint16_t itable_unused_lo;            /* Unused inodes count */
     244        uint16_t checksum;                    /* crc16(sb_uuid+group+desc) */
     245       
     246        uint32_t block_bitmap_hi;             /* Blocks bitmap block MSB */
     247        uint32_t inode_bitmap_hi;             /* I-nodes bitmap block MSB */
     248        uint32_t inode_table_first_block_hi;  /* I-nodes table block MSB */
     249        uint16_t free_blocks_count_hi;        /* Free blocks count MSB */
     250        uint16_t free_inodes_count_hi;        /* Free i-nodes count MSB */
     251        uint16_t used_dirs_count_hi;          /* Directories count MSB */
     252        uint16_t itable_unused_hi;            /* Unused inodes count MSB */
     253        uint32_t reserved2[3];                /* Padding */
    257254} ext4_block_group_t;
    258255
    259256typedef struct ext4_block_group_ref {
    260         block_t *block; // Reference to a block containing this block group descr
     257        block_t *block;                   /* Reference to a block containing this block group descr */
    261258        ext4_block_group_t *block_group;
    262259        ext4_filesystem_t *fs;
     
    265262} ext4_block_group_ref_t;
    266263
    267 
    268 #define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE 32
    269 #define EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE 64
    270 
    271 /*****************************************************************************/
    272 
    273 
    274 #define EXT4_MIN_BLOCK_SIZE             1024  //1 KiB
    275 #define EXT4_MAX_BLOCK_SIZE     65536 //64 KiB
    276 #define EXT4_REV0_INODE_SIZE    128
    277 
    278 #define EXT4_INODE_BLOCK_SIZE                           512
    279 
    280 #define EXT4_INODE_DIRECT_BLOCK_COUNT           12
    281 #define EXT4_INODE_INDIRECT_BLOCK                       EXT4_INODE_DIRECT_BLOCK_COUNT
    282 #define EXT4_INODE_DOUBLE_INDIRECT_BLOCK        (EXT4_INODE_INDIRECT_BLOCK + 1)
    283 #define EXT4_INODE_TRIPPLE_INDIRECT_BLOCK       (EXT4_INODE_DOUBLE_INDIRECT_BLOCK + 1)
    284 #define EXT4_INODE_BLOCKS                                       (EXT4_INODE_TRIPPLE_INDIRECT_BLOCK + 1)
    285 #define EXT4_INODE_INDIRECT_BLOCK_COUNT         (EXT4_INODE_BLOCKS - EXT4_INODE_DIRECT_BLOCK_COUNT)
     264#define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE  32
     265#define EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE  64
     266
     267#define EXT4_MIN_BLOCK_SIZE   1024   /* 1 KiB */
     268#define EXT4_MAX_BLOCK_SIZE   65536  /* 64 KiB */
     269#define EXT4_REV0_INODE_SIZE  128
     270
     271#define EXT4_INODE_BLOCK_SIZE  512
     272
     273#define EXT4_INODE_DIRECT_BLOCK_COUNT      12
     274#define EXT4_INODE_INDIRECT_BLOCK          EXT4_INODE_DIRECT_BLOCK_COUNT
     275#define EXT4_INODE_DOUBLE_INDIRECT_BLOCK   (EXT4_INODE_INDIRECT_BLOCK + 1)
     276#define EXT4_INODE_TRIPPLE_INDIRECT_BLOCK  (EXT4_INODE_DOUBLE_INDIRECT_BLOCK + 1)
     277#define EXT4_INODE_BLOCKS                  (EXT4_INODE_TRIPPLE_INDIRECT_BLOCK + 1)
     278#define EXT4_INODE_INDIRECT_BLOCK_COUNT    (EXT4_INODE_BLOCKS - EXT4_INODE_DIRECT_BLOCK_COUNT)
    286279
    287280/*
     
    289282 */
    290283typedef struct ext4_inode {
    291         uint16_t mode; // File mode
    292         uint16_t uid; // Low 16 bits of owner uid
    293         uint32_t size_lo; // Size in bytes
    294         uint32_t access_time; // Access time
    295         uint32_t change_inode_time; // Inode change time
    296         uint32_t modification_time; // Modification time
    297         uint32_t deletion_time; // Deletion time
    298         uint16_t gid; // Low 16 bits of group id
    299         uint16_t links_count; // Links count
    300         uint32_t blocks_count_lo; // Blocks count
    301         uint32_t flags; // File flags
    302         uint32_t unused_osd1; // OS dependent - not used in HelenOS
    303     uint32_t blocks[EXT4_INODE_BLOCKS]; // Pointers to blocks
    304     uint32_t generation; // File version (for NFS)
    305     uint32_t file_acl_lo; // File ACL
    306     uint32_t size_hi;
    307     uint32_t obso_faddr; // Obsoleted fragment address
    308     union {
    309         struct {
    310                 uint16_t blocks_high; /* were l_i_reserved1 */
    311                 uint16_t file_acl_high;
    312                 uint16_t uid_high;   /* these 2 fields */
    313                 uint16_t gid_high;   /* were reserved2[0] */
    314                 uint32_t reserved2;
    315         } linux2;
    316         struct {
    317                 uint16_t reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
    318                 uint16_t mode_high;
    319                 uint16_t uid_high;
    320                 uint16_t gid_high;
    321                 uint32_t author;
    322         } hurd2;
    323     } __attribute__ ((packed)) osd2;
    324 
    325     uint16_t extra_isize;
    326     uint16_t pad1;
    327     uint32_t ctime_extra; // Extra change time (nsec << 2 | epoch)
    328     uint32_t mtime_extra; // Extra Modification time (nsec << 2 | epoch)
    329     uint32_t atime_extra; // Extra Access time (nsec << 2 | epoch)
    330     uint32_t crtime; // File creation time
    331     uint32_t crtime_extra; // Extra file creation time (nsec << 2 | epoch)
    332     uint32_t version_hi;   // High 32 bits for 64-bit version
     284        uint16_t mode;                       /* File mode */
     285        uint16_t uid;                        /* Low 16 bits of owner uid */
     286        uint32_t size_lo;                    /* Size in bytes */
     287        uint32_t access_time;                /* Access time */
     288        uint32_t change_inode_time;          /* I-node change time */
     289        uint32_t modification_time;          /* Modification time */
     290        uint32_t deletion_time;              /* Deletion time */
     291        uint16_t gid;                        /* Low 16 bits of group id */
     292        uint16_t links_count;                /* Links count */
     293        uint32_t blocks_count_lo;            /* Blocks count */
     294        uint32_t flags;                      /* File flags */
     295        uint32_t unused_osd1;                /* OS dependent - not used in HelenOS */
     296        uint32_t blocks[EXT4_INODE_BLOCKS];  /* Pointers to blocks */
     297        uint32_t generation;                 /* File version (for NFS) */
     298        uint32_t file_acl_lo;                /* File ACL */
     299        uint32_t size_hi;
     300        uint32_t obso_faddr;                 /* Obsoleted fragment address */
     301       
     302        union {
     303                struct {
     304                        uint16_t blocks_high;
     305                        uint16_t file_acl_high;
     306                        uint16_t uid_high;
     307                        uint16_t gid_high;
     308                        uint32_t reserved2;
     309                } linux2;
     310                struct {
     311                        uint16_t reserved1;
     312                        uint16_t mode_high;
     313                        uint16_t uid_high;
     314                        uint16_t gid_high;
     315                        uint32_t author;
     316                } hurd2;
     317        } __attribute__ ((packed)) osd2;
     318       
     319        uint16_t extra_isize;
     320        uint16_t pad1;
     321        uint32_t ctime_extra;   /* Extra change time (nsec << 2 | epoch) */
     322        uint32_t mtime_extra;   /* Extra Modification time (nsec << 2 | epoch) */
     323        uint32_t atime_extra;   /* Extra Access time (nsec << 2 | epoch) */
     324        uint32_t crtime;        /* File creation time */
     325        uint32_t crtime_extra;  /* Extra file creation time (nsec << 2 | epoch) */
     326        uint32_t version_hi;    /* High 32 bits for 64-bit version */
    333327} __attribute__ ((packed)) ext4_inode_t;
    334328
    335 #define EXT4_INODE_MODE_FIFO            0x1000
    336 #define EXT4_INODE_MODE_CHARDEV         0x2000
    337 #define EXT4_INODE_MODE_DIRECTORY       0x4000
    338 #define EXT4_INODE_MODE_BLOCKDEV        0x6000
    339 #define EXT4_INODE_MODE_FILE            0x8000
    340 #define EXT4_INODE_MODE_SOFTLINK        0xA000
    341 #define EXT4_INODE_MODE_SOCKET          0xC000
    342 #define EXT4_INODE_MODE_TYPE_MASK       0xF000
     329#define EXT4_INODE_MODE_FIFO       0x1000
     330#define EXT4_INODE_MODE_CHARDEV    0x2000
     331#define EXT4_INODE_MODE_DIRECTORY  0x4000
     332#define EXT4_INODE_MODE_BLOCKDEV   0x6000
     333#define EXT4_INODE_MODE_FILE       0x8000
     334#define EXT4_INODE_MODE_SOFTLINK   0xA000
     335#define EXT4_INODE_MODE_SOCKET     0xC000
     336#define EXT4_INODE_MODE_TYPE_MASK  0xF000
    343337
    344338/*
    345339 * Inode flags
    346340 */
    347 #define EXT4_INODE_FLAG_SECRM           0x00000001 // Secure deletion
    348 #define EXT4_INODE_FLAG_UNRM            0x00000002 // Undelete
    349 #define EXT4_INODE_FLAG_COMPR           0x00000004 // Compress file
    350 #define EXT4_INODE_FLAG_SYNC            0x00000008 // Synchronous updates
    351 #define EXT4_INODE_FLAG_IMMUTABLE   0x00000010 // Immutable file
    352 #define EXT4_INODE_FLAG_APPEND          0x00000020 // writes to file may only append
    353 #define EXT4_INODE_FLAG_NODUMP          0x00000040 // do not dump file
    354 #define EXT4_INODE_FLAG_NOATIME         0x00000080 // do not update atime
     341#define EXT4_INODE_FLAG_SECRM      0x00000001  /* Secure deletion */
     342#define EXT4_INODE_FLAG_UNRM       0x00000002  /* Undelete */
     343#define EXT4_INODE_FLAG_COMPR      0x00000004  /* Compress file */
     344#define EXT4_INODE_FLAG_SYNC       0x00000008  /* Synchronous updates */
     345#define EXT4_INODE_FLAG_IMMUTABLE  0x00000010  /* Immutable file */
     346#define EXT4_INODE_FLAG_APPEND     0x00000020  /* writes to file may only append */
     347#define EXT4_INODE_FLAG_NODUMP     0x00000040  /* do not dump file */
     348#define EXT4_INODE_FLAG_NOATIME    0x00000080  /* do not update atime */
     349
    355350/* Compression flags */
    356 #define EXT4_INODE_FLAG_DIRTY           0x00000100
    357 #define EXT4_INODE_FLAG_COMPRBLK        0x00000200 // One or more compressed clusters
    358 #define EXT4_INODE_FLAG_NOCOMPR         0x00000400 // Don't compress
    359 #define EXT4_INODE_FLAG_ECOMPR          0x00000800 // Compression error
    360 /* End compression flags --- maybe not all used */
    361 #define EXT4_INODE_FLAG_INDEX           0x00001000 // hash-indexed directory
    362 #define EXT4_INODE_FLAG_IMAGIC          0x00002000 // AFS directory */
    363 #define EXT4_INODE_FLAG_JOURNAL_DATA    0x00004000 // File data should be journaled
    364 #define EXT4_INODE_FLAG_NOTAIL          0x00008000 // File tail should not be merged
    365 #define EXT4_INODE_FLAG_DIRSYNC         0x00010000 // Dirsync behaviour (directories only)
    366 #define EXT4_INODE_FLAG_TOPDIR          0x00020000 // Top of directory hierarchies
    367 #define EXT4_INODE_FLAG_HUGE_FILE       0x00040000 // Set to each huge file
    368 #define EXT4_INODE_FLAG_EXTENTS         0x00080000 // Inode uses extents
    369 #define EXT4_INODE_FLAG_EA_INODE        0x00200000 // Inode used for large EA
    370 #define EXT4_INODE_FLAG_EOFBLOCKS       0x00400000 // Blocks allocated beyond EOF
    371 #define EXT4_INODE_FLAG_RESERVED        0x80000000 // reserved for ext4 lib
    372 
    373 #define EXT4_INODE_ROOT_INDEX   2
     351#define EXT4_INODE_FLAG_DIRTY     0x00000100
     352#define EXT4_INODE_FLAG_COMPRBLK  0x00000200  /* One or more compressed clusters */
     353#define EXT4_INODE_FLAG_NOCOMPR   0x00000400  /* Don't compress */
     354#define EXT4_INODE_FLAG_ECOMPR    0x00000800  /* Compression error */
     355
     356#define EXT4_INODE_FLAG_INDEX         0x00001000  /* hash-indexed directory */
     357#define EXT4_INODE_FLAG_IMAGIC        0x00002000  /* AFS directory */
     358#define EXT4_INODE_FLAG_JOURNAL_DATA  0x00004000  /* File data should be journaled */
     359#define EXT4_INODE_FLAG_NOTAIL        0x00008000  /* File tail should not be merged */
     360#define EXT4_INODE_FLAG_DIRSYNC       0x00010000  /* Dirsync behaviour (directories only) */
     361#define EXT4_INODE_FLAG_TOPDIR        0x00020000  /* Top of directory hierarchies */
     362#define EXT4_INODE_FLAG_HUGE_FILE     0x00040000  /* Set to each huge file */
     363#define EXT4_INODE_FLAG_EXTENTS       0x00080000  /* Inode uses extents */
     364#define EXT4_INODE_FLAG_EA_INODE      0x00200000  /* Inode used for large EA */
     365#define EXT4_INODE_FLAG_EOFBLOCKS     0x00400000  /* Blocks allocated beyond EOF */
     366#define EXT4_INODE_FLAG_RESERVED      0x80000000  /* reserved for ext4 lib */
     367
     368#define EXT4_INODE_ROOT_INDEX  2
    374369
    375370typedef struct ext4_inode_ref {
    376         block_t *block; // Reference to a block containing this inode
     371        block_t *block;         /* Reference to a block containing this inode */
    377372        ext4_inode_t *inode;
    378373        ext4_filesystem_t *fs;
    379         uint32_t index; // Index number of this inode
     374        uint32_t index;         /* Index number of this inode */
    380375        bool dirty;
    381376} ext4_inode_ref_t;
    382377
    383 /*****************************************************************************/
    384 
    385 #define EXT4_DIRECTORY_FILENAME_LEN     255
    386 
    387 #define EXT4_DIRECTORY_FILETYPE_UNKNOWN         0
    388 #define EXT4_DIRECTORY_FILETYPE_REG_FILE        1
    389 #define EXT4_DIRECTORY_FILETYPE_DIR             2
    390 #define EXT4_DIRECTORY_FILETYPE_CHRDEV          3
    391 #define EXT4_DIRECTORY_FILETYPE_BLKDEV          4
    392 #define EXT4_DIRECTORY_FILETYPE_FIFO            5
    393 #define EXT4_DIRECTORY_FILETYPE_SOCK            6
    394 #define EXT4_DIRECTORY_FILETYPE_SYMLINK         7
     378
     379#define EXT4_DIRECTORY_FILENAME_LEN  255
     380
     381#define EXT4_DIRECTORY_FILETYPE_UNKNOWN   0
     382#define EXT4_DIRECTORY_FILETYPE_REG_FILE  1
     383#define EXT4_DIRECTORY_FILETYPE_DIR       2
     384#define EXT4_DIRECTORY_FILETYPE_CHRDEV    3
     385#define EXT4_DIRECTORY_FILETYPE_BLKDEV    4
     386#define EXT4_DIRECTORY_FILETYPE_FIFO      5
     387#define EXT4_DIRECTORY_FILETYPE_SOCK      6
     388#define EXT4_DIRECTORY_FILETYPE_SYMLINK   7
    395389
    396390/**
     
    398392 */
    399393typedef struct ext4_directory_entry_ll {
    400         uint32_t inode; // Inode for the entry
    401         uint16_t entry_length; // Distance to the next directory entry
    402         uint8_t name_length; // Lower 8 bits of name length
     394        uint32_t inode;         /* I-node for the entry */
     395        uint16_t entry_length;  /* Distance to the next directory entry */
     396        uint8_t name_length;    /* Lower 8 bits of name length */
     397       
    403398        union {
    404                 uint8_t name_length_high; // Higher 8 bits of name length
    405                 uint8_t inode_type; // Type of referenced inode (in rev >= 0.5)
     399                uint8_t name_length_high;  /* Higher 8 bits of name length */
     400                uint8_t inode_type;        /* Type of referenced inode (in rev >= 0.5) */
    406401        } __attribute__ ((packed));
    407         uint8_t name[EXT4_DIRECTORY_FILENAME_LEN]; // Entry name
    408 } __attribute__ ((packed)) ext4_directory_entry_ll_t;
     402       
     403        uint8_t name[EXT4_DIRECTORY_FILENAME_LEN];  /* Entry name */
     404} __attribute__((packed)) ext4_directory_entry_ll_t;
    409405
    410406typedef struct ext4_directory_iterator {
     
    420416} ext4_directory_search_result_t;
    421417
    422 
    423 /*****************************************************************************/
    424 
    425418/* Structures for indexed directory */
    426419
    427420typedef struct ext4_directory_dx_countlimit {
    428421        uint16_t limit;
    429     uint16_t count;
     422        uint16_t count;
    430423} ext4_directory_dx_countlimit_t;
    431424
     
    433426        uint32_t inode;
    434427        uint16_t entry_length;
    435     uint8_t name_length;
    436     uint8_t inode_type;
    437     uint8_t name[4];
     428        uint8_t name_length;
     429        uint8_t inode_type;
     430        uint8_t name[4];
    438431} ext4_directory_dx_dot_entry_t;
    439432
     
    452445
    453446typedef struct ext4_directory_dx_root {
    454                 ext4_directory_dx_dot_entry_t dots[2];
    455                 ext4_directory_dx_root_info_t info;
    456                 ext4_directory_dx_entry_t entries[0];
     447        ext4_directory_dx_dot_entry_t dots[2];
     448        ext4_directory_dx_root_info_t info;
     449        ext4_directory_dx_entry_t entries[0];
    457450} ext4_directory_dx_root_t;
    458451
     
    469462} ext4_directory_dx_node_t;
    470463
    471 
    472464typedef struct ext4_directory_dx_block {
    473465        block_t *block;
     
    476468} ext4_directory_dx_block_t;
    477469
    478 
    479 
    480 #define EXT4_ERR_BAD_DX_DIR                     (-75000)
    481 #define EXT4_DIRECTORY_HTREE_EOF        (uint32_t)0x7fffffff
    482 
    483 /*****************************************************************************/
     470#define EXT4_ERR_BAD_DX_DIR       (-75000)
     471#define EXT4_DIRECTORY_HTREE_EOF  UINT32_C(0x7fffffff)
    484472
    485473/*
     
    488476 */
    489477typedef struct ext4_extent {
    490         uint32_t first_block; // First logical block extent covers
    491         uint16_t block_count; // Number of blocks covered by extent
    492         uint16_t start_hi;    // High 16 bits of physical block
    493         uint32_t start_lo;    // Low 32 bits of physical block
     478        uint32_t first_block;  /* First logical block extent covers */
     479        uint16_t block_count;  /* Number of blocks covered by extent */
     480        uint16_t start_hi;     /* High 16 bits of physical block */
     481        uint32_t start_lo;     /* Low 32 bits of physical block */
    494482} ext4_extent_t;
    495483
     
    499487 */
    500488typedef struct ext4_extent_index {
    501         uint32_t first_block; // Index covers logical blocks from 'block'
    502         uint32_t leaf_lo; /* Pointer to the physical block of the next
    503                                            * level. leaf or next index could be there */
    504         uint16_t leaf_hi;     /* high 16 bits of physical block */
     489        uint32_t first_block;  /* Index covers logical blocks from 'block' */
     490       
     491        /**
     492         * Pointer to the physical block of the next
     493         * level. leaf or next index could be there
     494         * high 16 bits of physical block
     495         */
     496        uint32_t leaf_lo;
     497        uint16_t leaf_hi;
    505498        uint16_t padding;
    506499} ext4_extent_index_t;
     
    511504typedef struct ext4_extent_header {
    512505        uint16_t magic;
    513         uint16_t entries_count; // Number of valid entries
    514         uint16_t max_entries_count; // Capacity of store in entries
    515         uint16_t depth; // Has tree real underlying blocks?
    516         uint32_t generation; // generation of the tree
     506        uint16_t entries_count;      /* Number of valid entries */
     507        uint16_t max_entries_count;  /* Capacity of store in entries */
     508        uint16_t depth;              /* Has tree real underlying blocks? */
     509        uint32_t generation;         /* generation of the tree */
    517510} ext4_extent_header_t;
    518511
     
    525518} ext4_extent_path_t;
    526519
    527 #define EXT4_EXTENT_MAGIC       0xF30A
    528 #define EXT4_EXTENT_FIRST(header)       \
    529                 ((ext4_extent_t *) (((void *) (header)) + sizeof(ext4_extent_header_t)))
    530 #define EXT4_EXTENT_FIRST_INDEX(header) \
    531                 ((ext4_extent_index_t *) (((void *) (header)) + sizeof(ext4_extent_header_t)))
    532 
    533 /*****************************************************************************/
    534 
    535 #define EXT4_HASH_VERSION_LEGACY                        0
    536 #define EXT4_HASH_VERSION_HALF_MD4                      1
    537 #define EXT4_HASH_VERSION_TEA                           2
    538 #define EXT4_HASH_VERSION_LEGACY_UNSIGNED       3
    539 #define EXT4_HASH_VERSION_HALF_MD4_UNSIGNED     4
    540 #define EXT4_HASH_VERSION_TEA_UNSIGNED          5
     520#define EXT4_EXTENT_MAGIC  0xF30A
     521
     522#define EXT4_EXTENT_FIRST(header) \
     523        ((ext4_extent_t *) (((void *) (header)) + sizeof(ext4_extent_header_t)))
     524
     525#define EXT4_EXTENT_FIRST_INDEX(header) \
     526        ((ext4_extent_index_t *) (((void *) (header)) + sizeof(ext4_extent_header_t)))
     527
     528#define EXT4_HASH_VERSION_LEGACY             0
     529#define EXT4_HASH_VERSION_HALF_MD4           1
     530#define EXT4_HASH_VERSION_TEA                2
     531#define EXT4_HASH_VERSION_LEGACY_UNSIGNED    3
     532#define EXT4_HASH_VERSION_HALF_MD4_UNSIGNED  4
     533#define EXT4_HASH_VERSION_TEA_UNSIGNED       5
    541534
    542535typedef struct ext4_hash_info {
  • uspace/srv/fs/ext4fs/Makefile

    rb08e7970 r38542dc  
    2828
    2929USPACE_PREFIX = ../../..
    30 LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBFS_PREFIX)/libfs.a $(LIBEXT4_PREFIX)/libext4.a $(LIBPOSIX_PREFIX)/libposix.a
    31 EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX) -I$(LIBEXT4_PREFIX) -I$(LIBPOSIX_PREFIX)
     30LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBFS_PREFIX)/libfs.a $(LIBEXT4_PREFIX)/libext4.a
     31EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX) -I$(LIBEXT4_PREFIX)
    3232BINARY = ext4fs
    3333
  • uspace/srv/fs/ext4fs/ext4fs.c

    rb08e7970 r38542dc  
    2929/** @addtogroup fs
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        ext4fs.c
    35  * @brief       EXT4 file system driver for HelenOS.
     33 * @file  ext4fs.c
     34 * @brief Ext4 file system driver for HelenOS.
    3635 */
    3736
     
    4645#include "../../vfs/vfs.h"
    4746
    48 #define NAME    "ext4fs"
     47#define NAME  "ext4fs"
    4948
    5049vfs_info_t ext4fs_vfs_info = {
    5150        .name = NAME,
    52         .instance = 0,
     51        .instance = 0
    5352};
    5453
    55 /**
    56  * Entry point of ext4fs server.
    57  * Initialize data structures and IPC, then accepts connections in server mode.
    58  */
    5954int main(int argc, char **argv)
    6055{
    61         printf(NAME ": HelenOS EXT4 file system server\n");
    62 
     56        printf("%s: HelenOS EXT4 file system server\n", NAME);
     57       
    6358        if (argc == 3) {
    6459                if (!str_cmp(argv[1], "--instance"))
    6560                        ext4fs_vfs_info.instance = strtol(argv[2], NULL, 10);
    6661                else {
    67                         printf(NAME " Unrecognized parameters\n");
    68                         return -1;
     62                        printf("%s: Unrecognized parameters\n", NAME);
     63                        return 1;
    6964                }
    7065        }
    71 
     66       
    7267        async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
    73                 SERVICE_VFS, 0, 0);
     68            SERVICE_VFS, 0, 0);
    7469        if (!vfs_sess) {
    75                 printf(NAME ": failed to connect to VFS\n");
    76                 return -1;
     70                printf("%s: Failed to connect to VFS\n", NAME);
     71                return 2;
    7772        }
    78 
     73       
    7974        int rc = ext4fs_global_init();
    8075        if (rc != EOK) {
    81                 printf(NAME ": Failed global initialization\n");
    82                 return 1;
     76                printf("%s: Global initialization failed\n", NAME);
     77                return rc;
    8378        }
    84 
     79       
    8580        rc = fs_register(vfs_sess, &ext4fs_vfs_info, &ext4fs_ops,
    8681            &ext4fs_libfs_ops);
    8782        if (rc != EOK) {
    88                 fprintf(stdout, NAME ": Failed to register fs (%d)\n", rc);
    89                 return 1;
     83                printf("%s: Failed to register file system\n", NAME);
     84                return rc;
    9085        }
    91 
    92         printf(NAME ": Accepting connections\n");
     86       
     87        printf("%s: Accepting connections\n", NAME);
    9388        task_retval(0);
    9489        async_manager();
    95         /* not reached */
     90       
     91        /* Not reached */
    9692        return 0;
    9793}
     
    9995/**
    10096 * @}
    101  */ 
     97 */
  • uspace/srv/fs/ext4fs/ext4fs.h

    rb08e7970 r38542dc  
    2929/** @addtogroup fs
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef EXT4FS_EXT4FS_H_
  • uspace/srv/fs/ext4fs/ext4fs_ops.c

    rb08e7970 r38542dc  
    2929/** @addtogroup fs
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        ext4fs_ops.c
    35  * @brief       VFS operations for EXT4 filesystem.
     33 * @file  ext4fs_ops.c
     34 * @brief VFS operations for ext4 filesystem.
    3635 */
    3736
     
    4241#include <macros.h>
    4342#include <malloc.h>
    44 #include <string.h>
    4543#include <adt/hash_table.h>
    4644#include <ipc/loc.h>
     
    4846#include "../../vfs/vfs.h"
    4947
    50 #define EXT4FS_NODE(node)       ((node) ? (ext4fs_node_t *) (node)->data : NULL)
    51 
    52 #define OPEN_NODES_KEYS 2
    53 #define OPEN_NODES_DEV_HANDLE_KEY 0
    54 #define OPEN_NODES_INODE_KEY 1
    55 #define OPEN_NODES_BUCKETS 256
     48#define EXT4FS_NODE(node) \
     49        ((node) ? (ext4fs_node_t *) (node)->data : NULL)
     50
     51#define OPEN_NODES_KEYS  2
     52
     53#define OPEN_NODES_DEV_HANDLE_KEY  0
     54#define OPEN_NODES_INODE_KEY       1
     55
     56#define OPEN_NODES_BUCKETS  256
    5657
    5758/**
     
    8788static int ext4fs_node_put_core(ext4fs_node_t *);
    8889
    89 /* Forward declarations of EXT4 libfs operations. */
     90/* Forward declarations of ext4 libfs operations. */
    9091
    9192static int ext4fs_root_get(fs_node_t **, service_id_t);
     
    122123/** Compare given item with values in hash table.
    123124 *
    124  * @return      bool result of compare operation
    125125 */
    126126static int open_nodes_compare(unsigned long key[], hash_count_t keys,
    127127    link_t *item)
    128128{
    129         ext4fs_node_t *enode = hash_table_get_instance(item, ext4fs_node_t, link);
    130129        assert(keys > 0);
     130       
     131        ext4fs_node_t *enode =
     132            hash_table_get_instance(item, ext4fs_node_t, link);
     133       
    131134        if (enode->instance->service_id !=
    132             ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY])) {
     135            ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY]))
    133136                return false;
    134         }
    135         if (keys == 1) {
     137       
     138        if (keys == 1)
    136139                return true;
    137         }
     140       
    138141        assert(keys == 2);
     142       
    139143        return (enode->inode_ref->index == key[OPEN_NODES_INODE_KEY]);
    140144}
     
    154158};
    155159
    156 
    157160/** Basic initialization of the driver.
    158161 *
    159  * There is only needed to create hash table for storing open nodes.
    160  *
    161  * @return      error code
     162 * This is only needed to create the hash table
     163 * for storing open nodes.
     164 *
     165 * @return Error code
     166 *
    162167 */
    163168int ext4fs_global_init(void)
    164169{
    165170        if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS,
    166             OPEN_NODES_KEYS, &open_nodes_ops)) {
     171            OPEN_NODES_KEYS, &open_nodes_ops))
    167172                return ENOMEM;
    168         }
     173       
    169174        return EOK;
    170175}
     
    172177/* Finalization of the driver.
    173178 *
    174  * There is only needed to destroy hash table.
    175  *
    176  * @return      error code
     179 * This is only needed to destroy the hash table.
     180 *
     181 * @return Error code
    177182 */
    178183int ext4fs_global_fini(void)
     
    182187}
    183188
    184 
    185189/*
    186  * EXT4 libfs operations.
     190 * Ext4 libfs operations.
    187191 */
    188192
    189193/** Get instance from internal table by service_id.
    190194 *
    191  * @param service_id    device identifier
    192  * @param inst          output instance if successful operation
    193  * @return              error code
     195 * @param service_id Device identifier
     196 * @param inst       Output instance if successful operation
     197 *
     198 * @return Error code
     199 *
    194200 */
    195201int ext4fs_instance_get(service_id_t service_id, ext4fs_instance_t **inst)
    196202{
    197203        fibril_mutex_lock(&instance_list_mutex);
    198 
     204       
    199205        if (list_empty(&instance_list)) {
    200206                fibril_mutex_unlock(&instance_list_mutex);
    201207                return EINVAL;
    202208        }
    203 
    204         ext4fs_instance_t *tmp;
     209       
    205210        list_foreach(instance_list, link) {
    206                 tmp = list_get_instance(link, ext4fs_instance_t, link);
    207 
     211                ext4fs_instance_t *tmp =
     212                    list_get_instance(link, ext4fs_instance_t, link);
     213               
    208214                if (tmp->service_id == service_id) {
    209215                        *inst = tmp;
     
    212218                }
    213219        }
    214 
     220       
    215221        fibril_mutex_unlock(&instance_list_mutex);
    216222        return EINVAL;
    217223}
    218224
    219 
    220225/** Get root node of filesystem specified by service_id.
    221226 *
    222  * @param rfn           output pointer to loaded node
    223  * @param service_id    device to load root node from
    224  * @return              error code
     227 * @param rfn        Output pointer to loaded node
     228 * @param service_id Device to load root node from
     229 *
     230 * @return Error code
     231 *
    225232 */
    226233int ext4fs_root_get(fs_node_t **rfn, service_id_t service_id)
     
    233240 * If match is found, load and return matching node.
    234241 *
    235  * @param rfn           output pointer to node if operation successful
    236  * @param pfn           parent directory node
    237  * @param component     name to check directory for
    238  * @return              error code
     242 * @param rfn       Output pointer to node if operation successful
     243 * @param pfn       Parent directory node
     244 * @param component Name to check directory for
     245 *
     246 * @return Error code
     247 *
    239248 */
    240249int ext4fs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    241250{
    242         int rc;
    243 
    244251        ext4fs_node_t *eparent = EXT4FS_NODE(pfn);
    245252        ext4_filesystem_t *fs = eparent->instance->filesystem;
    246 
     253       
    247254        if (!ext4_inode_is_type(fs->superblock, eparent->inode_ref->inode,
    248             EXT4_INODE_MODE_DIRECTORY)) {
     255            EXT4_INODE_MODE_DIRECTORY))
    249256                return ENOTDIR;
    250         }
    251 
     257       
    252258        /* Try to find entry */
    253259        ext4_directory_search_result_t result;
    254         rc = ext4_directory_find_entry(&result, eparent->inode_ref, component);
     260        int rc = ext4_directory_find_entry(&result, eparent->inode_ref,
     261            component);
    255262        if (rc != EOK) {
    256263                if (rc == ENOENT) {
     
    258265                        return EOK;
    259266                }
    260                 return rc;
    261         }
    262 
     267               
     268                return rc;
     269        }
     270       
    263271        /* Load node from search result */
    264272        uint32_t inode = ext4_directory_entry_ll_get_inode(result.dentry);
    265273        rc = ext4fs_node_get_core(rfn, eparent->instance, inode);
    266         if (rc != EOK) {
    267                 return rc;
    268         }
    269 
     274        if (rc != EOK)
     275                return rc;
     276       
    270277        /* Destroy search result structure */
    271         rc = ext4_directory_destroy_result(&result);
    272         if (rc != EOK) {
    273                 return rc;
    274         }
    275 
    276         return EOK;
     278        return ext4_directory_destroy_result(&result);
    277279}
    278280
     
    281283 * It's wrapper for node_put_core operation
    282284 *
    283  * @param rfn           output pointer to loaded node if operation successful
    284  * @param service_id    device identifier
    285  * @param index         node index (here i-node number)
    286  * @return              error code
     285 * @param rfn        Output pointer to loaded node if operation successful
     286 * @param service_id Device identifier
     287 * @param index      Node index (here i-node number)
     288 *
     289 * @return Error code
     290 *
    287291 */
    288292int ext4fs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
    289293{
    290         int rc;
    291 
    292294        ext4fs_instance_t *inst;
    293         rc = ext4fs_instance_get(service_id, &inst);
    294         if (rc != EOK) {
    295                 return rc;
    296         }
    297 
     295        int rc = ext4fs_instance_get(service_id, &inst);
     296        if (rc != EOK)
     297                return rc;
     298       
    298299        return ext4fs_node_get_core(rfn, inst, index);
    299300}
     
    301302/** Main function for getting node from the filesystem.
    302303 *
    303  * @param rfn           output point to loaded node if operation successful
    304  * @param inst          instance of filesystem
    305  * @param index         index of node (i-node number)
    306  * @return              error code
     304 * @param rfn   Output point to loaded node if operation successful
     305 * @param inst  Instance of filesystem
     306 * @param index Index of node (i-node number)
     307 *
     308 * @return Error code
     309 *
    307310 */
    308311int ext4fs_node_get_core(fs_node_t **rfn, ext4fs_instance_t *inst,
    309                 fs_index_t index)
    310 {
    311         int rc;
    312 
     312    fs_index_t index)
     313{
    313314        fibril_mutex_lock(&open_nodes_lock);
    314 
     315       
    315316        /* Check if the node is not already open */
    316317        unsigned long key[] = {
    317318                [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id,
    318                 [OPEN_NODES_INODE_KEY] = index,
     319                [OPEN_NODES_INODE_KEY] = index
    319320        };
    320 
     321       
    321322        link_t *already_open = hash_table_find(&open_nodes, key);
    322323        ext4fs_node_t *enode = NULL;
     
    325326                *rfn = enode->fs_node;
    326327                enode->references++;
    327 
     328               
    328329                fibril_mutex_unlock(&open_nodes_lock);
    329330                return EOK;
    330331        }
    331 
     332       
    332333        /* Prepare new enode */
    333334        enode = malloc(sizeof(ext4fs_node_t));
     
    336337                return ENOMEM;
    337338        }
    338 
     339       
    339340        /* Prepare new fs_node and initialize */
    340341        fs_node_t *fs_node = malloc(sizeof(fs_node_t));
     
    344345                return ENOMEM;
    345346        }
     347       
    346348        fs_node_initialize(fs_node);
    347 
     349       
    348350        /* Load i-node from filesystem */
    349351        ext4_inode_ref_t *inode_ref;
    350         rc = ext4_filesystem_get_inode_ref(inst->filesystem, index, &inode_ref);
     352        int rc = ext4_filesystem_get_inode_ref(inst->filesystem, index,
     353            &inode_ref);
    351354        if (rc != EOK) {
    352355                free(enode);
     
    355358                return rc;
    356359        }
    357 
     360       
    358361        /* Initialize enode */
    359362        enode->inode_ref = inode_ref;
     
    362365        enode->fs_node = fs_node;
    363366        link_initialize(&enode->link);
    364 
     367       
    365368        fs_node->data = enode;
    366369        *rfn = fs_node;
    367 
     370       
    368371        hash_table_insert(&open_nodes, key, &enode->link);
    369372        inst->open_nodes_count++;
    370 
     373       
    371374        fibril_mutex_unlock(&open_nodes_lock);
    372 
     375       
    373376        return EOK;
    374377}
     
    376379/** Put previously loaded node.
    377380 *
    378  * @param enode         node to put back
    379  * @return              error code
     381 * @param enode Node to put back
     382 *
     383 * @return Error code
     384 *
    380385 */
    381386int ext4fs_node_put_core(ext4fs_node_t *enode)
    382387{
    383         int rc;
    384388        unsigned long key[] = {
    385389                [OPEN_NODES_DEV_HANDLE_KEY] = enode->instance->service_id,
    386                 [OPEN_NODES_INODE_KEY] = enode->inode_ref->index,
     390                [OPEN_NODES_INODE_KEY] = enode->inode_ref->index
    387391        };
    388 
     392       
    389393        hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS);
    390394        assert(enode->instance->open_nodes_count > 0);
    391395        enode->instance->open_nodes_count--;
    392 
     396       
    393397        /* Put inode back in filesystem */
    394         rc = ext4_filesystem_put_inode_ref(enode->inode_ref);
    395         if (rc != EOK) {
    396                 return rc;
    397         }
    398 
     398        int rc = ext4_filesystem_put_inode_ref(enode->inode_ref);
     399        if (rc != EOK)
     400                return rc;
     401       
    399402        /* Destroy data structure */
    400403        free(enode->fs_node);
    401404        free(enode);
    402 
     405       
    403406        return EOK;
    404407}
    405408
    406 
    407409/** Open node.
    408410 *
    409411 * This operation is stateless in this driver.
    410412 *
    411  * @param fn    node to open
    412  * @return      error code (EOK)
     413 * @param fn Node to open
     414 *
     415 * @return EOK
     416 *
    413417 */
    414418int ext4fs_node_open(fs_node_t *fn)
     
    418422}
    419423
    420 
    421424/** Put previously loaded node.
    422425 *
    423  * It's wrapper for node_put_core operation
    424  *
    425  * @param fn    node to put back
    426  * @return      error code
     426 * A wrapper for node_put_core operation
     427 *
     428 * @param fn Node to put back
     429 * @return Error code
     430 *
    427431 */
    428432int ext4fs_node_put(fs_node_t *fn)
    429433{
    430         int rc;
    431 
    432434        fibril_mutex_lock(&open_nodes_lock);
    433 
     435       
    434436        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    435437        assert(enode->references > 0);
    436438        enode->references--;
    437439        if (enode->references == 0) {
    438                 rc = ext4fs_node_put_core(enode);
     440                int rc = ext4fs_node_put_core(enode);
    439441                if (rc != EOK) {
    440442                        fibril_mutex_unlock(&open_nodes_lock);
     
    442444                }
    443445        }
    444 
     446       
    445447        fibril_mutex_unlock(&open_nodes_lock);
    446 
     448       
    447449        return EOK;
    448450}
    449451
    450 
    451452/** Create new node in filesystem.
    452453 *
    453  * @param rfn           output pointer to newly created node if successful
    454  * @param service_id    device identifier, where the filesystem is
    455  * @param flags         flags for specification of new node parameters
    456  * @return              error code
     454 * @param rfn        Output pointer to newly created node if successful
     455 * @param service_id Device identifier, where the filesystem is
     456 * @param flags      Flags for specification of new node parameters
     457 *
     458 * @return Error code
     459 *
    457460 */
    458461int ext4fs_create_node(fs_node_t **rfn, service_id_t service_id, int flags)
    459462{
    460         int rc;
    461 
    462463        /* Allocate enode */
    463464        ext4fs_node_t *enode;
    464465        enode = malloc(sizeof(ext4fs_node_t));
    465         if (enode == NULL) {
     466        if (enode == NULL)
    466467                return ENOMEM;
    467         }
    468 
     468       
    469469        /* Allocate fs_node */
    470470        fs_node_t *fs_node;
     
    474474                return ENOMEM;
    475475        }
    476 
     476       
    477477        /* Load instance */
    478478        ext4fs_instance_t *inst;
    479         rc = ext4fs_instance_get(service_id, &inst);
     479        int rc = ext4fs_instance_get(service_id, &inst);
    480480        if (rc != EOK) {
    481481                free(enode);
     
    483483                return rc;
    484484        }
    485 
     485       
    486486        /* Allocate new i-node in filesystem */
    487487        ext4_inode_ref_t *inode_ref;
     
    492492                return rc;
    493493        }
    494 
     494       
    495495        /* Do some interconnections in references */
    496496        enode->inode_ref = inode_ref;
    497497        enode->instance = inst;
    498498        enode->references = 1;
    499 
     499       
    500500        link_initialize(&enode->link);
    501 
     501       
    502502        unsigned long key[] = {
    503503                [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id,
    504                 [OPEN_NODES_INODE_KEY] = inode_ref->index,
     504                [OPEN_NODES_INODE_KEY] = inode_ref->index
    505505        };
    506 
     506       
    507507        fibril_mutex_lock(&open_nodes_lock);
    508508        hash_table_insert(&open_nodes, key, &enode->link);
    509509        fibril_mutex_unlock(&open_nodes_lock);
    510510        inst->open_nodes_count++;
    511 
     511       
    512512        enode->inode_ref->dirty = true;
    513 
     513       
    514514        fs_node_initialize(fs_node);
    515515        fs_node->data = enode;
    516516        enode->fs_node = fs_node;
    517517        *rfn = fs_node;
    518 
     518       
    519519        return EOK;
    520520}
    521521
    522 
    523522/** Destroy existing node.
    524523 *
    525  * @param fs    node to destroy
    526  * @return      error code
     524 * @param fs Node to destroy
     525 *
     526 * @return Error code
     527 *
    527528 */
    528529int ext4fs_destroy_node(fs_node_t *fn)
    529530{
    530         int rc;
    531 
    532531        /* If directory, check for children */
    533532        bool has_children;
    534         rc = ext4fs_has_children(&has_children, fn);
     533        int rc = ext4fs_has_children(&has_children, fn);
    535534        if (rc != EOK) {
    536535                ext4fs_node_put(fn);
    537536                return rc;
    538537        }
    539 
     538       
    540539        if (has_children) {
    541540                ext4fs_node_put(fn);
    542541                return EINVAL;
    543542        }
    544 
     543       
    545544        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    546545        ext4_inode_ref_t *inode_ref = enode->inode_ref;
    547 
     546       
    548547        /* Release data blocks */
    549548        rc = ext4_filesystem_truncate_inode(inode_ref, 0);
     
    552551                return rc;
    553552        }
    554 
    555         // TODO set real deletion time when it will be supported, temporary set fake time
    556 //      time_t now = time(NULL);
     553       
     554        /*
     555         * TODO: Sset real deletion time when it will be supported.
     556         * Temporary set fake deletion time.
     557         */
    557558        ext4_inode_set_deletion_time(inode_ref->inode, 0xdeadbeef);
    558559        inode_ref->dirty = true;
    559 
     560       
    560561        /* Free inode */
    561562        rc = ext4_filesystem_free_inode(inode_ref);
     
    564565                return rc;
    565566        }
    566 
     567       
    567568        return ext4fs_node_put(fn);
    568569}
    569570
    570 
    571571/** Link the specfied node to directory.
    572572 *
    573  * @param pfn           parent node to link in
    574  * @param cfn           node to be linked
    575  * @param name          name which will be assigned to directory entry
    576  * @return              error code
     573 * @param pfn  Parent node to link in
     574 * @param cfn  Node to be linked
     575 * @param name Name which will be assigned to directory entry
     576 *
     577 * @return Error code
     578 *
    577579 */
    578580int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
    579581{
    580         int rc;
    581 
    582582        /* Check maximum name length */
    583         if (strlen(name) > EXT4_DIRECTORY_FILENAME_LEN) {
     583        if (str_size(name) > EXT4_DIRECTORY_FILENAME_LEN)
    584584                return ENAMETOOLONG;
    585         }
     585       
    586586        ext4fs_node_t *parent = EXT4FS_NODE(pfn);
    587587        ext4fs_node_t *child = EXT4FS_NODE(cfn);
    588588        ext4_filesystem_t *fs = parent->instance->filesystem;
    589 
     589       
    590590        /* Add entry to parent directory */
    591         rc = ext4_directory_add_entry(parent->inode_ref, name, child->inode_ref);
    592         if (rc != EOK) {
    593                 return rc;
    594         }
    595 
     591        int rc = ext4_directory_add_entry(parent->inode_ref, name,
     592            child->inode_ref);
     593        if (rc != EOK)
     594                return rc;
     595       
    596596        /* Fill new dir -> add '.' and '..' entries */
    597         if (ext4_inode_is_type(fs->superblock, child->inode_ref->inode, EXT4_INODE_MODE_DIRECTORY)) {
    598 
    599                 rc = ext4_directory_add_entry(child->inode_ref, ".", child->inode_ref);
     597        if (ext4_inode_is_type(fs->superblock, child->inode_ref->inode,
     598            EXT4_INODE_MODE_DIRECTORY)) {
     599                rc = ext4_directory_add_entry(child->inode_ref, ".",
     600                    child->inode_ref);
    600601                if (rc != EOK) {
    601602                        ext4_directory_remove_entry(parent->inode_ref, name);
    602603                        return rc;
    603604                }
    604 
    605                 rc = ext4_directory_add_entry(child->inode_ref, "..", parent->inode_ref);
     605               
     606                rc = ext4_directory_add_entry(child->inode_ref, "..",
     607                    parent->inode_ref);
    606608                if (rc != EOK) {
    607609                        ext4_directory_remove_entry(parent->inode_ref, name);
     
    609611                        return rc;
    610612                }
    611 
     613               
    612614                /* Initialize directory index if supported */
    613                 if (ext4_superblock_has_feature_compatible(
    614                                 fs->superblock, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
    615 
     615                if (ext4_superblock_has_feature_compatible(fs->superblock,
     616                    EXT4_FEATURE_COMPAT_DIR_INDEX)) {
    616617                        rc = ext4_directory_dx_init(child->inode_ref);
    617                         if (rc != EOK) {
     618                        if (rc != EOK)
    618619                                return rc;
    619                         }
    620 
    621                         ext4_inode_set_flag(child->inode_ref->inode, EXT4_INODE_FLAG_INDEX);
     620                       
     621                        ext4_inode_set_flag(child->inode_ref->inode,
     622                            EXT4_INODE_FLAG_INDEX);
    622623                        child->inode_ref->dirty = true;
    623624                }
    624 
    625                 uint16_t parent_links = ext4_inode_get_links_count(parent->inode_ref->inode);
     625       
     626                uint16_t parent_links =
     627                    ext4_inode_get_links_count(parent->inode_ref->inode);
    626628                parent_links++;
    627629                ext4_inode_set_links_count(parent->inode_ref->inode, parent_links);
    628 
     630               
    629631                parent->inode_ref->dirty = true;
    630 
    631         }
    632 
    633         uint16_t child_links = ext4_inode_get_links_count(child->inode_ref->inode);
     632        }
     633       
     634        uint16_t child_links =
     635            ext4_inode_get_links_count(child->inode_ref->inode);
    634636        child_links++;
    635637        ext4_inode_set_links_count(child->inode_ref->inode, child_links);
    636 
     638       
    637639        child->inode_ref->dirty = true;
    638 
     640       
    639641        return EOK;
    640642}
    641643
    642 
    643644/** Unlink node from specified directory.
    644645 *
    645  * @param pfn           parent node to delete node from
    646  * @param cfn           child node to be unlinked from directory
    647  * @param name          name of entry that will be removed
    648  * @return              error code
     646 * @param pfn  Parent node to delete node from
     647 * @param cfn  Child node to be unlinked from directory
     648 * @param name Name of entry that will be removed
     649 *
     650 * @return Error code
     651 *
    649652 */
    650653int ext4fs_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *name)
    651654{
    652         int rc;
    653 
    654655        bool has_children;
    655         rc = ext4fs_has_children(&has_children, cfn);
    656         if (rc != EOK) {
    657                 return rc;
    658         }
    659 
     656        int rc = ext4fs_has_children(&has_children, cfn);
     657        if (rc != EOK)
     658                return rc;
     659       
    660660        /* Cannot unlink non-empty node */
    661         if (has_children) {
     661        if (has_children)
    662662                return ENOTEMPTY;
    663         }
    664 
     663       
    665664        /* Remove entry from parent directory */
    666665        ext4_inode_ref_t *parent = EXT4FS_NODE(pfn)->inode_ref;
    667666        rc = ext4_directory_remove_entry(parent, name);
    668         if (rc != EOK) {
    669                 return rc;
    670         }
    671 
     667        if (rc != EOK)
     668                return rc;
     669       
    672670        /* Decrement links count */
    673         ext4_inode_ref_t * child_inode_ref = EXT4FS_NODE(cfn)->inode_ref;
    674 
    675         uint32_t lnk_count = ext4_inode_get_links_count(child_inode_ref->inode);
     671        ext4_inode_ref_t *child_inode_ref = EXT4FS_NODE(cfn)->inode_ref;
     672       
     673        uint32_t lnk_count =
     674            ext4_inode_get_links_count(child_inode_ref->inode);
    676675        lnk_count--;
    677 
     676       
    678677        /* If directory - handle links from parent */
    679         if (lnk_count <= 1 && ext4fs_is_directory(cfn)) {
    680 
     678        if ((lnk_count <= 1) && (ext4fs_is_directory(cfn))) {
    681679                assert(lnk_count == 1);
     680               
    682681                lnk_count--;
    683 
     682               
    684683                ext4_inode_ref_t *parent_inode_ref = EXT4FS_NODE(pfn)->inode_ref;
    685 
     684               
    686685                uint32_t parent_lnk_count = ext4_inode_get_links_count(
    687                                 parent_inode_ref->inode);
    688 
     686                    parent_inode_ref->inode);
     687               
    689688                parent_lnk_count--;
    690689                ext4_inode_set_links_count(parent_inode_ref->inode, parent_lnk_count);
    691 
     690               
    692691                parent->dirty = true;
    693692        }
    694693
    695         // TODO set timestamps for parent (when we have wall-clock time)
    696 //      time_t now = time(NULL);
    697 //      ext4_inode_set_change_inode_time(parent->inode, (uint32_t)now);
    698 //      ext4_inode_set_modification_time(parent->inode, (uint32_t)now);
    699 //      parent->dirty = true;
    700 
    701         // TODO set timestamp for inode
    702 //      ext4_inode_set_change_inode_time(child_inode_ref->inode, (uint32_t)now);
     694        /*
     695         * TODO: Update timestamps of the parent
     696         * (when we have wall-clock time).
     697         *
     698         * ext4_inode_set_change_inode_time(parent->inode, (uint32_t) now);
     699         * ext4_inode_set_modification_time(parent->inode, (uint32_t) now);
     700         * parent->dirty = true;
     701         */
     702       
     703        /*
     704         * TODO: Update timestamp for inode.
     705         *
     706         * ext4_inode_set_change_inode_time(child_inode_ref->inode,
     707         *     (uint32_t) now);
     708         */
     709       
    703710        ext4_inode_set_links_count(child_inode_ref->inode, lnk_count);
    704711        child_inode_ref->dirty = true;
    705 
     712       
    706713        return EOK;
    707714}
    708715
    709 
    710716/** Check if specified node has children.
    711  * 
     717 *
    712718 * For files is response allways false and check is executed only for directories.
    713719 *
    714  * @param has_children          output value for response
    715  * @param fn                    node to check
    716  * @return                      error code
     720 * @param has_children Output value for response
     721 * @param fn           Node to check
     722 *
     723 * @return Error code
     724 *
    717725 */
    718726int ext4fs_has_children(bool *has_children, fs_node_t *fn)
    719727{
    720         int rc;
    721 
    722728        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    723729        ext4_filesystem_t *fs = enode->instance->filesystem;
    724 
     730       
    725731        /* Check if node is directory */
    726732        if (!ext4_inode_is_type(fs->superblock, enode->inode_ref->inode,
     
    729735                return EOK;
    730736        }
    731 
     737       
    732738        ext4_directory_iterator_t it;
    733         rc = ext4_directory_iterator_init(&it, enode->inode_ref, 0);
    734         if (rc != EOK) {
    735                 return rc;
    736         }
    737 
     739        int rc = ext4_directory_iterator_init(&it, enode->inode_ref, 0);
     740        if (rc != EOK)
     741                return rc;
     742       
    738743        /* Find a non-empty directory entry */
    739744        bool found = false;
    740745        while (it.current != NULL) {
    741746                if (it.current->inode != 0) {
    742                         uint16_t name_size = ext4_directory_entry_ll_get_name_length(fs->superblock,
    743                                 it.current);
     747                        uint16_t name_size =
     748                            ext4_directory_entry_ll_get_name_length(fs->superblock,
     749                            it.current);
    744750                        if (!ext4fs_is_dots(it.current->name, name_size)) {
    745751                                found = true;
     
    747753                        }
    748754                }
    749 
     755               
    750756                rc = ext4_directory_iterator_next(&it);
    751757                if (rc != EOK) {
     
    754760                }
    755761        }
    756 
     762       
    757763        rc = ext4_directory_iterator_fini(&it);
    758         if (rc != EOK) {
    759                 return rc;
    760         }
    761 
     764        if (rc != EOK)
     765                return rc;
     766       
    762767        *has_children = found;
    763 
     768       
    764769        return EOK;
    765770}
    766771
    767 
    768772/** Unpack index number from node.
    769  *     
    770  * @param fn    node to load index from
    771  * @return      index number of i-node
     773 *
     774 * @param fn Node to load index from
     775 *
     776 * @return Index number of i-node
     777 *
    772778 */
    773779fs_index_t ext4fs_index_get(fs_node_t *fn)
     
    777783}
    778784
    779 
    780785/** Get real size of file / directory.
    781786 *
    782  * @param fn    node to get size of
    783  * @return      real size of node
     787 * @param fn Node to get size of
     788 *
     789 * @return Real size of node
     790 *
    784791 */
    785792aoff64_t ext4fs_size_get(fs_node_t *fn)
     
    790797}
    791798
    792 
    793799/** Get number of links to specified node.
    794800 *
    795  * @param fn    node to get links to
    796  * @return      number of links
     801 * @param fn Node to get links to
     802 *
     803 * @return Number of links
     804 *
    797805 */
    798806unsigned ext4fs_lnkcnt_get(fs_node_t *fn)
     
    800808        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    801809        uint32_t lnkcnt = ext4_inode_get_links_count(enode->inode_ref->inode);
    802 
     810       
    803811        if (ext4fs_is_directory(fn)) {
    804                 if (lnkcnt > 1) {
     812                if (lnkcnt > 1)
    805813                        return 1;
    806                 } else {
     814                else
    807815                        return 0;
    808                 }
    809         }
    810 
     816        }
     817       
    811818        /* For regular files return real links count */
    812819        return lnkcnt;
    813820}
    814821
    815 
    816822/** Check if node is directory.
    817823 *
    818  * @param fn    node to check
    819  * @return      result of check
     824 * @param fn Node to check
     825 *
     826 * @return Result of check
     827 *
    820828 */
    821829bool ext4fs_is_directory(fs_node_t *fn)
     
    823831        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    824832        ext4_superblock_t *sb = enode->instance->filesystem->superblock;
    825         return ext4_inode_is_type(
    826                         sb, enode->inode_ref->inode, EXT4_INODE_MODE_DIRECTORY);
    827 }
    828 
     833       
     834        return ext4_inode_is_type(sb, enode->inode_ref->inode,
     835            EXT4_INODE_MODE_DIRECTORY);
     836}
    829837
    830838/** Check if node is regular file.
    831839 *
    832  * @param fn    node to check
    833  * @return      result of check
     840 * @param fn Node to check
     841 *
     842 * @return Result of check
     843 *
    834844 */
    835845bool ext4fs_is_file(fs_node_t *fn)
     
    837847        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    838848        ext4_superblock_t *sb = enode->instance->filesystem->superblock;
    839         return ext4_inode_is_type(
    840                         sb, enode->inode_ref->inode, EXT4_INODE_MODE_FILE);
     849       
     850        return ext4_inode_is_type(sb, enode->inode_ref->inode,
     851            EXT4_INODE_MODE_FILE);
    841852}
    842853
    843854/** Extract device identifier from node.
    844855 *
    845  * @param node  node to extract id from
    846  * @return      id of device, where is the filesystem
     856 * @param node Node to extract id from
     857 *
     858 * @return id of device, where is the filesystem
     859 *
    847860 */
    848861service_id_t ext4fs_service_get(fs_node_t *fn)
     
    874887};
    875888
    876 
    877889/*
    878890 * VFS operations.
    879891 */
    880892
    881 /** Mount operation. 
     893/** Mount operation.
    882894 *
    883895 * Try to mount specified filesystem from device.
    884  *
    885  * @param service_id    identifier of device
    886  * @param opts          mount options
    887  * @param index         output value - index of root node
    888  * @param size          output value - size of root node
    889  * @param lnkcnt        output value - link count of root node
    890  * @return              error code
     896 *
     897 * @param service_id Identifier of device
     898 * @param opts       Mount options
     899 * @param index      Output value - index of root node
     900 * @param size       Output value - size of root node
     901 * @param lnkcnt     Output value - link count of root node
     902 *
     903 * @return Error code
     904 *
    891905 */
    892906static int ext4fs_mounted(service_id_t service_id, const char *opts,
    893    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
    894 {
    895         int rc;
    896 
     907    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     908{
    897909        /* Allocate libext4 filesystem structure */
    898         ext4_filesystem_t *fs;
    899         fs = (ext4_filesystem_t *) malloc(sizeof(ext4_filesystem_t));
    900         if (fs == NULL) {
     910        ext4_filesystem_t *fs = (ext4_filesystem_t *)
     911            malloc(sizeof(ext4_filesystem_t));
     912        if (fs == NULL)
    901913                return ENOMEM;
    902         }
    903 
     914       
    904915        /* Allocate instance structure */
    905         ext4fs_instance_t *inst;
    906         inst = (ext4fs_instance_t *) malloc(sizeof(ext4fs_instance_t));
     916        ext4fs_instance_t *inst = (ext4fs_instance_t *)
     917            malloc(sizeof(ext4fs_instance_t));
    907918        if (inst == NULL) {
    908919                free(fs);
    909920                return ENOMEM;
    910921        }
    911 
     922       
    912923        enum cache_mode cmode;
    913         if (str_cmp(opts, "wtcache") == 0) {
     924        if (str_cmp(opts, "wtcache") == 0)
    914925                cmode = CACHE_MODE_WT;
    915         } else {
     926        else
    916927                cmode = CACHE_MODE_WB;
    917         }
    918 
     928       
    919929        /* Initialize the filesystem */
    920         rc = ext4_filesystem_init(fs, service_id, cmode);
     930        int rc = ext4_filesystem_init(fs, service_id, cmode);
    921931        if (rc != EOK) {
    922932                free(fs);
     
    924934                return rc;
    925935        }
    926 
     936       
    927937        /* Do some sanity checking */
    928938        rc = ext4_filesystem_check_sanity(fs);
     
    933943                return rc;
    934944        }
    935 
     945       
    936946        /* Check flags */
    937947        bool read_only;
     
    943953                return rc;
    944954        }
    945 
     955       
    946956        /* Initialize instance */
    947957        link_initialize(&inst->link);
     
    949959        inst->filesystem = fs;
    950960        inst->open_nodes_count = 0;
    951 
     961       
    952962        /* Read root node */
    953963        fs_node_t *root_node;
     
    959969                return rc;
    960970        }
    961 
     971       
    962972        /* Add instance to the list */
    963973        fibril_mutex_lock(&instance_list_mutex);
    964974        list_append(&inst->link, &instance_list);
    965975        fibril_mutex_unlock(&instance_list_mutex);
    966 
     976       
    967977        ext4fs_node_t *enode = EXT4FS_NODE(root_node);
    968 
     978       
    969979        *index = EXT4_INODE_ROOT_INDEX;
    970980        *size = ext4_inode_get_size(fs->superblock, enode->inode_ref->inode);
    971981        *lnkcnt = 1;
    972 
     982       
    973983        ext4fs_node_put(root_node);
    974 
     984       
    975985        return EOK;
    976986}
     
    980990 * Correctly release the filesystem.
    981991 *
    982  * @param service_id    device to be unmounted
    983  * @return              error code
     992 * @param service_id Device to be unmounted
     993 *
     994 * @return Error code
     995 *
    984996 */
    985997static int ext4fs_unmounted(service_id_t service_id)
    986998{
    987         int rc;
    988 
    989999        ext4fs_instance_t *inst;
    990         rc = ext4fs_instance_get(service_id, &inst);
    991         if (rc != EOK) {
    992                 return rc;
    993         }
    994 
     1000        int rc = ext4fs_instance_get(service_id, &inst);
     1001        if (rc != EOK)
     1002                return rc;
     1003       
    9951004        fibril_mutex_lock(&open_nodes_lock);
    996 
     1005       
    9971006        if (inst->open_nodes_count != 0) {
    9981007                fibril_mutex_unlock(&open_nodes_lock);
    9991008                return EBUSY;
    10001009        }
    1001 
     1010       
    10021011        /* Remove the instance from the list */
    10031012        fibril_mutex_lock(&instance_list_mutex);
    10041013        list_remove(&inst->link);
    10051014        fibril_mutex_unlock(&instance_list_mutex);
    1006 
     1015       
    10071016        fibril_mutex_unlock(&open_nodes_lock);
    1008 
     1017       
    10091018        return ext4_filesystem_fini(inst->filesystem);
    10101019}
    10111020
    1012 
    10131021/** Read bytes from node.
    10141022 *
    1015  * @param service_id    device to read data from
    1016  * @param index         number of node to read from
    1017  * @param pos           position where the read should be started
    1018  * @param rbytes        output value, where the real size was returned
    1019  * @return              error code
    1020  */
    1021 static int ext4fs_read(service_id_t service_id, fs_index_t index,
    1022                 aoff64_t pos, size_t *rbytes)
    1023 {
    1024         int rc;
    1025 
     1023 * @param service_id Device to read data from
     1024 * @param index      Number of node to read from
     1025 * @param pos        Position where the read should be started
     1026 * @param rbytes     Output value, where the real size was returned
     1027 *
     1028 * @return Error code
     1029 *
     1030 */
     1031static int ext4fs_read(service_id_t service_id, fs_index_t index, aoff64_t pos,
     1032    size_t *rbytes)
     1033{
    10261034        /*
    10271035         * Receive the read request.
     
    10331041                return EINVAL;
    10341042        }
    1035 
     1043       
    10361044        ext4fs_instance_t *inst;
    1037         rc = ext4fs_instance_get(service_id, &inst);
     1045        int rc = ext4fs_instance_get(service_id, &inst);
    10381046        if (rc != EOK) {
    10391047                async_answer_0(callid, rc);
    10401048                return rc;
    10411049        }
    1042 
     1050       
    10431051        /* Load i-node */
    10441052        ext4_inode_ref_t *inode_ref;
     
    10481056                return rc;
    10491057        }
    1050 
     1058       
    10511059        /* Read from i-node by type */
    10521060        if (ext4_inode_is_type(inst->filesystem->superblock, inode_ref->inode,
    1053                         EXT4_INODE_MODE_FILE)) {
     1061            EXT4_INODE_MODE_FILE)) {
    10541062                rc = ext4fs_read_file(callid, pos, size, inst, inode_ref,
    1055                                 rbytes);
     1063                    rbytes);
    10561064        } else if (ext4_inode_is_type(inst->filesystem->superblock,
    1057                         inode_ref->inode, EXT4_INODE_MODE_DIRECTORY)) {
     1065            inode_ref->inode, EXT4_INODE_MODE_DIRECTORY)) {
    10581066                rc = ext4fs_read_directory(callid, pos, size, inst, inode_ref,
    1059                                 rbytes);
     1067                    rbytes);
    10601068        } else {
    10611069                /* Other inode types not supported */
     
    10631071                rc = ENOTSUP;
    10641072        }
    1065 
     1073       
    10661074        ext4_filesystem_put_inode_ref(inode_ref);
    1067 
     1075       
    10681076        return rc;
    10691077}
     
    10711079/** Check if filename is dot or dotdot (reserved names).
    10721080 *
    1073  * @param name          name to check
    1074  * @param name_size     length of string name
    1075  * @return              result of the check
     1081 * @param name      Name to check
     1082 * @param name_size Length of string name
     1083 *
     1084 * @return Result of the check
     1085 *
    10761086 */
    10771087bool ext4fs_is_dots(const uint8_t *name, size_t name_size)
    10781088{
    1079         if (name_size == 1 && name[0] == '.') {
     1089        if ((name_size == 1) && (name[0] == '.'))
    10801090                return true;
    1081         }
    1082 
    1083         if (name_size == 2 && name[0] == '.' && name[1] == '.') {
     1091       
     1092        if ((name_size == 2) && (name[0] == '.') && (name[1] == '.'))
    10841093                return true;
    1085         }
    1086 
     1094       
    10871095        return false;
    10881096}
     
    10901098/** Read data from directory.
    10911099 *
    1092  * @param callid        IPC id of call (for communication)
    1093  * @param pos           position to start reading from
    1094  * @param size          how many bytes to read
    1095  * @param inst          filesystem instance
    1096  * @param inode_ref     node to read data from
    1097  * @param rbytes        output value to return real number of bytes was read
    1098  * @return              error code
     1100 * @param callid    IPC id of call (for communication)
     1101 * @param pos       Position to start reading from
     1102 * @param size      How many bytes to read
     1103 * @param inst      Filesystem instance
     1104 * @param inode_ref Node to read data from
     1105 * @param rbytes    Output value to return real number of bytes was read
     1106 *
     1107 * @return Error code
     1108 *
    10991109 */
    11001110int ext4fs_read_directory(ipc_callid_t callid, aoff64_t pos, size_t size,
    11011111    ext4fs_instance_t *inst, ext4_inode_ref_t *inode_ref, size_t *rbytes)
    11021112{
    1103         int rc;
    1104 
    11051113        ext4_directory_iterator_t it;
    1106         rc = ext4_directory_iterator_init(&it, inode_ref, pos);
     1114        int rc = ext4_directory_iterator_init(&it, inode_ref, pos);
    11071115        if (rc != EOK) {
    11081116                async_answer_0(callid, rc);
    11091117                return rc;
    11101118        }
    1111 
    1112         /* Find next interesting directory entry.
     1119       
     1120        /*
     1121         * Find next interesting directory entry.
    11131122         * We want to skip . and .. entries
    11141123         * as these are not used in HelenOS
     
    11161125        bool found = false;
    11171126        while (it.current != NULL) {
    1118 
    1119                 if (it.current->inode == 0) {
     1127                if (it.current->inode == 0)
    11201128                        goto skip;
    1121                 }
    1122 
     1129               
    11231130                uint16_t name_size = ext4_directory_entry_ll_get_name_length(
    11241131                    inst->filesystem->superblock, it.current);
    1125 
    1126                 /* skip . and .. */
    1127                 if (ext4fs_is_dots(it.current->name, name_size)) {
     1132               
     1133                /* Skip . and .. */
     1134                if (ext4fs_is_dots(it.current->name, name_size))
    11281135                        goto skip;
    1129                 }
    1130 
    1131                 /* The on-disk entry does not contain \0 at the end
     1136               
     1137                /*
     1138                 * The on-disk entry does not contain \0 at the end
    11321139                 * end of entry name, so we copy it to new buffer
    11331140                 * and add the \0 at the end
    11341141                 */
    1135                 uint8_t *buf = malloc(name_size+1);
     1142                uint8_t *buf = malloc(name_size + 1);
    11361143                if (buf == NULL) {
    11371144                        ext4_directory_iterator_fini(&it);
     
    11391146                        return ENOMEM;
    11401147                }
     1148               
    11411149                memcpy(buf, &it.current->name, name_size);
    11421150                *(buf + name_size) = 0;
    11431151                found = true;
     1152               
    11441153                (void) async_data_read_finalize(callid, buf, name_size + 1);
    11451154                free(buf);
    11461155                break;
    1147 
     1156               
    11481157skip:
    11491158                rc = ext4_directory_iterator_next(&it);
     
    11541163                }
    11551164        }
    1156 
     1165       
    11571166        uint64_t next;
    11581167        if (found) {
    11591168                rc = ext4_directory_iterator_next(&it);
    1160                 if (rc != EOK) {
     1169                if (rc != EOK)
    11611170                        return rc;
    1162                 }
     1171               
    11631172                next = it.current_offset;
    11641173        }
    1165 
     1174       
    11661175        rc = ext4_directory_iterator_fini(&it);
    1167         if (rc != EOK) {
    1168                 return rc;
    1169         }
    1170 
     1176        if (rc != EOK)
     1177                return rc;
     1178       
    11711179        /* Prepare return values */
    11721180        if (found) {
     
    11791187}
    11801188
    1181 
    11821189/** Read data from file.
    11831190 *
    1184  * @param callid        IPC id of call (for communication)
    1185  * @param pos           position to start reading from
    1186  * @param size          how many bytes to read
    1187  * @param inst          filesystem instance
    1188  * @param inode_ref     node to read data from
    1189  * @param rbytes        output value to return real number of bytes was read
    1190  * @return              error code
     1191 * @param callid    IPC id of call (for communication)
     1192 * @param pos       Position to start reading from
     1193 * @param size      How many bytes to read
     1194 * @param inst      Filesystem instance
     1195 * @param inode_ref Node to read data from
     1196 * @param rbytes    Output value to return real number of bytes was read
     1197 *
     1198 * @return Error code
     1199 *
    11911200 */
    11921201int ext4fs_read_file(ipc_callid_t callid, aoff64_t pos, size_t size,
    11931202    ext4fs_instance_t *inst, ext4_inode_ref_t *inode_ref, size_t *rbytes)
    11941203{
    1195         int rc;
    1196 
    11971204        ext4_superblock_t *sb = inst->filesystem->superblock;
    11981205        uint64_t file_size = ext4_inode_get_size(sb, inode_ref->inode);
    1199 
     1206       
    12001207        if (pos >= file_size) {
    12011208                /* Read 0 bytes successfully */
     
    12041211                return EOK;
    12051212        }
    1206 
     1213       
    12071214        /* For now, we only read data from one block at a time */
    12081215        uint32_t block_size = ext4_superblock_get_block_size(sb);
     
    12101217        uint32_t offset_in_block = pos % block_size;
    12111218        uint32_t bytes = min(block_size - offset_in_block, size);
    1212 
     1219       
    12131220        /* Handle end of file */
    1214         if (pos + bytes > file_size) {
     1221        if (pos + bytes > file_size)
    12151222                bytes = file_size - pos;
    1216         }
    1217 
     1223       
    12181224        /* Get the real block number */
    12191225        uint32_t fs_block;
    1220         rc = ext4_filesystem_get_inode_data_block_index(inode_ref, file_block, &fs_block);
     1226        int rc = ext4_filesystem_get_inode_data_block_index(inode_ref,
     1227            file_block, &fs_block);
    12211228        if (rc != EOK) {
    12221229                async_answer_0(callid, rc);
    12231230                return rc;
    12241231        }
    1225 
    1226         /* Check for sparse file
     1232       
     1233        /*
     1234         * Check for sparse file.
    12271235         * If ext4_filesystem_get_inode_data_block_index returned
    12281236         * fs_block == 0, it means that the given block is not allocated for the
     
    12361244                        return ENOMEM;
    12371245                }
    1238 
     1246               
    12391247                memset(buffer, 0, bytes);
    1240 
     1248               
    12411249                async_data_read_finalize(callid, buffer, bytes);
    12421250                *rbytes = bytes;
    1243 
     1251               
    12441252                free(buffer);
    1245 
    12461253                return EOK;
    12471254        }
    1248 
     1255       
    12491256        /* Usual case - we need to read a block from device */
    12501257        block_t *block;
     
    12541261                return rc;
    12551262        }
    1256 
     1263       
    12571264        assert(offset_in_block + bytes <= block_size);
    12581265        async_data_read_finalize(callid, block->data + offset_in_block, bytes);
    1259 
     1266       
    12601267        rc = block_put(block);
    1261         if (rc != EOK) {
    1262                 return rc;
    1263         }
    1264 
     1268        if (rc != EOK)
     1269                return rc;
     1270       
    12651271        *rbytes = bytes;
    12661272        return EOK;
    12671273}
    12681274
    1269 
    12701275/** Write bytes to file
    12711276 *
    1272  * @param service_id    device identifier
    1273  * @param index         i-node number of file
    1274  * @param pos           position in file to start reading from
    1275  * @param wbytes        output value - real number of written bytes
    1276  * @param nsize         output value - new size of i-node
    1277  * @return              error code
    1278  */
    1279 static int ext4fs_write(service_id_t service_id, fs_index_t index,
    1280                 aoff64_t pos, size_t *wbytes, aoff64_t *nsize)
    1281 {
    1282         int rc;
    1283 
     1277 * @param service_id Device identifier
     1278 * @param index      I-node number of file
     1279 * @param pos        Position in file to start reading from
     1280 * @param wbytes     Output value - real number of written bytes
     1281 * @param nsize      Output value - new size of i-node
     1282 *
     1283 * @return Error code
     1284 *
     1285 */
     1286static int ext4fs_write(service_id_t service_id, fs_index_t index, aoff64_t pos,
     1287    size_t *wbytes, aoff64_t *nsize)
     1288{
    12841289        fs_node_t *fn;
    1285         rc = ext4fs_node_get(&fn, service_id, index);
    1286         if (rc != EOK) {
    1287                 return rc;
    1288         }
    1289 
     1290        int rc = ext4fs_node_get(&fn, service_id, index);
     1291        if (rc != EOK)
     1292                return rc;
     1293       
    12901294        ipc_callid_t callid;
    12911295        size_t len;
    12921296        if (!async_data_write_receive(&callid, &len)) {
    1293                 rc = EINVAL;
     1297                ext4fs_node_put(fn);
     1298                async_answer_0(callid, EINVAL);
     1299                return EINVAL;
     1300        }
     1301       
     1302        ext4fs_node_t *enode = EXT4FS_NODE(fn);
     1303        ext4_filesystem_t *fs = enode->instance->filesystem;
     1304       
     1305        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
     1306       
     1307        /* Prevent writing to more than one block */
     1308        uint32_t bytes = min(len, block_size - (pos % block_size));
     1309       
     1310        int flags = BLOCK_FLAGS_NONE;
     1311        if (bytes == block_size)
     1312                flags = BLOCK_FLAGS_NOREAD;
     1313       
     1314        uint32_t iblock =  pos / block_size;
     1315        uint32_t fblock;
     1316       
     1317        /* Load inode */
     1318        ext4_inode_ref_t *inode_ref = enode->inode_ref;
     1319        rc = ext4_filesystem_get_inode_data_block_index(inode_ref, iblock,
     1320            &fblock);
     1321        if (rc != EOK) {
    12941322                ext4fs_node_put(fn);
    12951323                async_answer_0(callid, rc);
    12961324                return rc;
    12971325        }
    1298 
    1299 
    1300         ext4fs_node_t *enode = EXT4FS_NODE(fn);
    1301         ext4_filesystem_t *fs = enode->instance->filesystem;
    1302 
    1303         uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    1304 
    1305         /* Prevent writing to more than one block */
    1306         uint32_t bytes = min(len, block_size - (pos % block_size));
    1307 
    1308         int flags = BLOCK_FLAGS_NONE;
    1309         if (bytes == block_size) {
    1310                 flags = BLOCK_FLAGS_NOREAD;
    1311         }
    1312 
    1313         uint32_t iblock =  pos / block_size;
    1314         uint32_t fblock;
    1315 
    1316         /* Load inode */
    1317         ext4_inode_ref_t *inode_ref = enode->inode_ref;
    1318         rc = ext4_filesystem_get_inode_data_block_index(inode_ref, iblock, &fblock);
    1319         if (rc != EOK) {
    1320                 ext4fs_node_put(fn);
    1321                 async_answer_0(callid, rc);
    1322                 return rc;
    1323         }
    1324 
     1326       
    13251327        /* Check for sparse file */
    13261328        if (fblock == 0) {
    1327 
    1328                 if (ext4_superblock_has_feature_incompatible(
    1329                                 fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    1330                                 (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
    1331 
    1332                         uint32_t last_iblock = ext4_inode_get_size(fs->superblock, inode_ref->inode) / block_size;
     1329                if ((ext4_superblock_has_feature_incompatible(fs->superblock,
     1330                    EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     1331                    (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
     1332                        uint32_t last_iblock =
     1333                            ext4_inode_get_size(fs->superblock, inode_ref->inode) /
     1334                            block_size;
     1335                       
    13331336                        while (last_iblock < iblock) {
    1334                                 rc = ext4_extent_append_block(inode_ref, &last_iblock, &fblock, true);
     1337                                rc = ext4_extent_append_block(inode_ref, &last_iblock,
     1338                                    &fblock, true);
    13351339                                if (rc != EOK) {
    13361340                                        ext4fs_node_put(fn);
     
    13391343                                }
    13401344                        }
    1341 
    1342                         rc = ext4_extent_append_block(inode_ref, &last_iblock, &fblock, false);
     1345                       
     1346                        rc = ext4_extent_append_block(inode_ref, &last_iblock,
     1347                            &fblock, false);
    13431348                        if (rc != EOK) {
    13441349                                ext4fs_node_put(fn);
     
    13461351                                return rc;
    13471352                        }
    1348 
    13491353                } else {
    1350                         rc =  ext4_balloc_alloc_block(inode_ref, &fblock);
     1354                        rc = ext4_balloc_alloc_block(inode_ref, &fblock);
    13511355                        if (rc != EOK) {
    13521356                                ext4fs_node_put(fn);
     
    13541358                                return rc;
    13551359                        }
    1356 
    1357                         rc = ext4_filesystem_set_inode_data_block_index(inode_ref, iblock, fblock);
     1360                       
     1361                        rc = ext4_filesystem_set_inode_data_block_index(inode_ref,
     1362                            iblock, fblock);
    13581363                        if (rc != EOK) {
    13591364                                ext4_balloc_free_block(inode_ref, fblock);
     
    13631368                        }
    13641369                }
    1365 
     1370               
    13661371                flags = BLOCK_FLAGS_NOREAD;
    13671372                inode_ref->dirty = true;
    13681373        }
    1369 
     1374       
    13701375        /* Load target block */
    13711376        block_t *write_block;
     
    13761381                return rc;
    13771382        }
    1378 
    1379         if (flags == BLOCK_FLAGS_NOREAD) {
     1383       
     1384        if (flags == BLOCK_FLAGS_NOREAD)
    13801385                memset(write_block->data, 0, block_size);
    1381         }
    1382 
    1383         rc = async_data_write_finalize(callid, write_block->data + (pos % block_size), bytes);
     1386       
     1387        rc = async_data_write_finalize(callid, write_block->data +
     1388            (pos % block_size), bytes);
    13841389        if (rc != EOK) {
    13851390                ext4fs_node_put(fn);
    13861391                return rc;
    13871392        }
    1388 
     1393       
    13891394        write_block->dirty = true;
    1390 
     1395       
    13911396        rc = block_put(write_block);
    13921397        if (rc != EOK) {
     
    13941399                return rc;
    13951400        }
    1396 
     1401       
    13971402        /* Do some counting */
    1398         uint32_t old_inode_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
     1403        uint32_t old_inode_size = ext4_inode_get_size(fs->superblock,
     1404            inode_ref->inode);
    13991405        if (pos + bytes > old_inode_size) {
    14001406                ext4_inode_set_size(inode_ref->inode, pos + bytes);
    14011407                inode_ref->dirty = true;
    14021408        }
    1403 
     1409       
    14041410        *nsize = ext4_inode_get_size(fs->superblock, inode_ref->inode);
    14051411        *wbytes = bytes;
    1406 
     1412       
    14071413        return ext4fs_node_put(fn);
    14081414}
    14091415
    1410 
    14111416/** Truncate file.
    14121417 *
    14131418 * Only the direction to shorter file is supported.
    14141419 *
    1415  * @param service_id    device identifier
    1416  * @param index         index if node to truncated
    1417  * @param new_size      new size of file
    1418  * @return              error code
     1420 * @param service_id Device identifier
     1421 * @param index      Index if node to truncated
     1422 * @param new_size   New size of file
     1423 *
     1424 * @return Error code
     1425 *
    14191426 */
    14201427static int ext4fs_truncate(service_id_t service_id, fs_index_t index,
    1421                 aoff64_t new_size)
    1422 {
    1423         int rc;
    1424 
     1428    aoff64_t new_size)
     1429{
    14251430        fs_node_t *fn;
    1426         rc = ext4fs_node_get(&fn, service_id, index);
    1427         if (rc != EOK) {
    1428                 return rc;
    1429         }
    1430 
     1431        int rc = ext4fs_node_get(&fn, service_id, index);
     1432        if (rc != EOK)
     1433                return rc;
     1434       
    14311435        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    14321436        ext4_inode_ref_t *inode_ref = enode->inode_ref;
    1433 
     1437       
    14341438        rc = ext4_filesystem_truncate_inode(inode_ref, new_size);
    14351439        ext4fs_node_put(fn);
    1436 
     1440       
    14371441        return rc;
    14381442}
    14391443
    1440 
    14411444/** Close file.
    14421445 *
    1443  * @param service_id    device identifier
    1444  * @param index         i-node number
    1445  * @return              error code
     1446 * @param service_id Device identifier
     1447 * @param index      I-node number
     1448 *
     1449 * @return Error code
     1450 *
    14461451 */
    14471452static int ext4fs_close(service_id_t service_id, fs_index_t index)
     
    14501455}
    14511456
    1452 
    14531457/** Destroy node specified by index.
    14541458 *
    1455  * @param service_id    device identifier
    1456  * @param index         number of i-node to destroy
    1457  * @return              error code
     1459 * @param service_id Device identifier
     1460 * @param index      I-node to destroy
     1461 *
     1462 * @return Error code
     1463 *
    14581464 */
    14591465static int ext4fs_destroy(service_id_t service_id, fs_index_t index)
    14601466{
    1461         int rc;
    1462 
    14631467        fs_node_t *fn;
    1464         rc = ext4fs_node_get(&fn, service_id, index);
    1465         if (rc != EOK) {
    1466                 return rc;
    1467         }
    1468 
     1468        int rc = ext4fs_node_get(&fn, service_id, index);
     1469        if (rc != EOK)
     1470                return rc;
     1471       
    14691472        /* Destroy the inode */
    14701473        return ext4fs_destroy_node(fn);
    14711474}
    14721475
    1473 /** Enforce inode synchronization (write) to device.
    1474  *
    1475  * @param service_id    device identifier
    1476  * @param index         i-node number.
     1476/** Enforce inode synchronization (write) to device.
     1477 *
     1478 * @param service_id Device identifier
     1479 * @param index      I-node number.
     1480 *
    14771481 */
    14781482static int ext4fs_sync(service_id_t service_id, fs_index_t index)
    14791483{
    1480         int rc;
    1481 
    14821484        fs_node_t *fn;
    1483         rc = ext4fs_node_get(&fn, service_id, index);
    1484         if (rc != EOK) {
    1485                 return rc;
    1486         }
    1487 
     1485        int rc = ext4fs_node_get(&fn, service_id, index);
     1486        if (rc != EOK)
     1487                return rc;
     1488       
    14881489        ext4fs_node_t *enode = EXT4FS_NODE(fn);
    14891490        enode->inode_ref->dirty = true;
    1490 
     1491       
    14911492        return ext4fs_node_put(fn);
    14921493}
     
    15031504        .close = ext4fs_close,
    15041505        .destroy = ext4fs_destroy,
    1505         .sync = ext4fs_sync,
     1506        .sync = ext4fs_sync
    15061507};
    15071508
Note: See TracChangeset for help on using the changeset viewer.