Changeset beb9336 in mainline for uspace/lib/ext4/libext4_filesystem.c


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

Merge with mainline

File:
1 edited

Legend:

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

    rbd29f9c9 rbeb9336  
    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 
    100         if (state != EXT4_SUPERBLOCK_STATE_VALID_FS) {
     97       
     98        if (((state & EXT4_SUPERBLOCK_STATE_VALID_FS) !=
     99            EXT4_SUPERBLOCK_STATE_VALID_FS) ||
     100            ((state & EXT4_SUPERBLOCK_STATE_ERROR_FS) ==
     101            EXT4_SUPERBLOCK_STATE_ERROR_FS)) {
    101102                block_cache_fini(fs->device);
    102103                block_fini(fs->device);
    103104                return ENOTSUP;
    104105        }
    105 
     106       
    106107        /* Mark system as mounted */
    107108        ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_ERROR_FS);
     
    112113                return rc;
    113114        }
    114 
     115       
    115116        uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock);
    116117        ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1);
    117 
     118       
    118119        return EOK;
    119120}
     
    121122/** Destroy filesystem instance (used by unmount operation).
    122123 *
    123  * @param fs            filesystem to be destroyed
    124  * @param write_sb      flag if superblock should be written to device
    125  * @return                      error code
     124 * @param fs Filesystem to be destroyed
     125 *
     126 * @return Error code
     127 *
    126128 */
    127129int ext4_filesystem_fini(ext4_filesystem_t *fs)
    128130{
    129         int rc = EOK;
    130 
    131131        /* Write the superblock to the device */
    132132        ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_VALID_FS);
    133         rc = ext4_superblock_write_direct(fs->device, fs->superblock);
    134 
     133        int rc = ext4_superblock_write_direct(fs->device, fs->superblock);
     134       
    135135        /* Release memory space for superblock */
    136136        free(fs->superblock);
    137 
     137       
    138138        /* Finish work with block library */
    139139        block_cache_fini(fs->device);
    140140        block_fini(fs->device);
    141 
     141       
    142142        return rc;
    143143}
     
    147147 * Main is the check of the superblock structure.
    148148 *
    149  * @param fs            filesystem to be checked
    150  * @return                      error code
     149 * @param fs Filesystem to be checked
     150 *
     151 * @return Error code
     152 *
    151153 */
    152154int ext4_filesystem_check_sanity(ext4_filesystem_t *fs)
    153155{
    154         int rc;
    155 
    156156        /* Check superblock */
    157         rc = ext4_superblock_check_sanity(fs->superblock);
    158         if (rc != EOK) {
    159                 return rc;
    160         }
    161 
    162         return EOK;
     157        return ext4_superblock_check_sanity(fs->superblock);
    163158}
    164159
     
    169164 * during some write operations.
    170165 *
    171  * @param fs                    filesystem to be checked
    172  * @param read_only             flag if filesystem should be mounted only for reading
    173  * @return                              error code
     166 * @param fs        Filesystem to be checked
     167 * @param read_only Flag if filesystem should be mounted only for reading
     168 *
     169 * @return Error code
     170 *
    174171 */
    175172int ext4_filesystem_check_features(ext4_filesystem_t *fs, bool *read_only)
     
    180177                return EOK;
    181178        }
    182 
    183         /* Check incompatible features - if filesystem has some,
     179       
     180        /*
     181         * Check incompatible features - if filesystem has some,
    184182         * volume can't be mounted
    185183         */
    186184        uint32_t incompatible_features;
    187         incompatible_features = ext4_superblock_get_features_incompatible(fs->superblock);
     185        incompatible_features =
     186            ext4_superblock_get_features_incompatible(fs->superblock);
    188187        incompatible_features &= ~EXT4_FEATURE_INCOMPAT_SUPP;
    189         if (incompatible_features > 0) {
     188        if (incompatible_features > 0)
    190189                return ENOTSUP;
    191         }
    192 
    193         /* Check read-only features, if filesystem has some,
     190       
     191        /*
     192         * Check read-only features, if filesystem has some,
    194193         * volume can be mount only in read-only mode
    195194         */
    196195        uint32_t compatible_read_only;
    197         compatible_read_only = ext4_superblock_get_features_read_only(fs->superblock);
     196        compatible_read_only =
     197            ext4_superblock_get_features_read_only(fs->superblock);
    198198        compatible_read_only &= ~EXT4_FEATURE_RO_COMPAT_SUPP;
    199199        if (compatible_read_only > 0) {
     
    201201                return EOK;
    202202        }
    203 
     203       
    204204        return EOK;
    205205}
     
    208208/** Convert block address to relative index in block group.
    209209 *
    210  * @param sb                    superblock pointer
    211  * @param block_addr    block number to convert
    212  * @return                              relative number of block
     210 * @param sb         Superblock pointer
     211 * @param block_addr Block number to convert
     212 *
     213 * @return Relative number of block
     214 *
    213215 */
    214216uint32_t ext4_filesystem_blockaddr2_index_in_group(ext4_superblock_t *sb,
    215                 uint32_t block_addr)
     217    uint32_t block_addr)
    216218{
    217219        uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
    218220        uint32_t first_block = ext4_superblock_get_first_data_block(sb);
    219 
     221       
    220222        /* First block == 0 or 1 */
    221         if (first_block == 0) {
     223        if (first_block == 0)
    222224                return block_addr % blocks_per_group;
    223         } else {
     225        else
    224226                return (block_addr - 1) % blocks_per_group;
    225         }
    226227}
    227228
     
    229230/** Convert relative block address in group to absolute address.
    230231 *
    231  * @param sb                    superblock pointer
    232  * @param block_addr    block number to convert
    233  * @return                              absolute block address
     232 * @param sb Superblock pointer
     233 *
     234 * @return Absolute block address
     235 *
    234236 */
    235237uint32_t ext4_filesystem_index_in_group2blockaddr(ext4_superblock_t *sb,
    236                 uint32_t index, uint32_t bgid)
     238    uint32_t index, uint32_t bgid)
    237239{
    238240        uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
    239 
    240         if (ext4_superblock_get_first_data_block(sb) == 0) {
     241       
     242        if (ext4_superblock_get_first_data_block(sb) == 0)
    241243                return bgid * blocks_per_group + index;
    242         } else {
     244        else
    243245                return bgid * blocks_per_group + index + 1;
    244         }
    245 
    246246}
    247247
    248248/** Initialize block bitmap in block group.
    249  *
    250  * @param bg_ref        reference to block group
    251  * @return                      error code
     249 *
     250 * @param bg_ref Reference to block group
     251 *
     252 * @return Error code
     253 *
    252254 */
    253255static int ext4_filesystem_init_block_bitmap(ext4_block_group_ref_t *bg_ref)
    254256{
    255         int rc;
    256 
    257257        /* Load bitmap */
    258258        uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
    259                         bg_ref->block_group, bg_ref->fs->superblock);
     259            bg_ref->block_group, bg_ref->fs->superblock);
     260       
    260261        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) {
     262        int rc = block_get(&bitmap_block, bg_ref->fs->device,
     263            bitmap_block_addr, BLOCK_FLAGS_NOREAD);
     264        if (rc != EOK)
    265265                return rc;
    266         }
    267 
     266       
    268267        uint8_t *bitmap = bitmap_block->data;
    269 
     268       
    270269        /* Initialize all bitmap bits to zero */
    271270        uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock);
    272271        memset(bitmap, 0, block_size);
    273 
     272       
    274273        /* Determine first block and first data block in group */
    275274        uint32_t first_idx = 0;
    276 
     275       
    277276        uint32_t first_data = ext4_balloc_get_first_data_block_in_group(
    278                         bg_ref->fs->superblock, bg_ref);
     277            bg_ref->fs->superblock, bg_ref);
    279278        uint32_t first_data_idx = ext4_filesystem_blockaddr2_index_in_group(
    280                         bg_ref->fs->superblock, first_data);
    281 
     279            bg_ref->fs->superblock, first_data);
     280       
    282281        /* 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) {
     282        for (uint32_t block = first_idx; block < first_data_idx; ++block)
    284283                ext4_bitmap_set_bit(bitmap, block);
    285         }
    286 
     284       
    287285        bitmap_block->dirty = true;
    288 
     286       
    289287        /* Save bitmap */
    290         rc = block_put(bitmap_block);
    291         if (rc != EOK) {
    292                 return rc;
    293         }
    294 
    295         return EOK;
     288        return block_put(bitmap_block);
    296289}
    297290
    298291/** Initialize i-node bitmap in block group.
    299  *
    300  * @param bg_ref        reference to block group
    301  * @return                      error code
     292 *
     293 * @param bg_ref Reference to block group
     294 *
     295 * @return Error code
     296 *
    302297 */
    303298static int ext4_filesystem_init_inode_bitmap(ext4_block_group_ref_t *bg_ref)
    304299{
    305         int rc;
    306 
    307300        /* Load bitmap */
    308301        uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
    309                         bg_ref->block_group, bg_ref->fs->superblock);
     302            bg_ref->block_group, bg_ref->fs->superblock);
    310303        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) {
     304       
     305        int rc = block_get(&bitmap_block, bg_ref->fs->device,
     306            bitmap_block_addr, BLOCK_FLAGS_NOREAD);
     307        if (rc != EOK)
    315308                return rc;
    316         }
    317 
     309       
    318310        uint8_t *bitmap = bitmap_block->data;
    319 
     311       
    320312        /* Initialize all bitmap bits to zero */
    321313        uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock);
    322314        uint32_t inodes_per_group =
    323                         ext4_superblock_get_inodes_per_group(bg_ref->fs->superblock);
     315            ext4_superblock_get_inodes_per_group(bg_ref->fs->superblock);
    324316        memset(bitmap, 0, (inodes_per_group + 7) / 8);
    325 
     317       
    326318        uint32_t start_bit = inodes_per_group;
    327319        uint32_t end_bit = block_size * 8;
    328 
     320       
    329321        uint32_t i;
    330         for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++) {
     322        for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
    331323                ext4_bitmap_set_bit(bitmap, i);
    332         }
    333 
    334         if (i < end_bit) {
     324       
     325        if (i < end_bit)
    335326                memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
    336         }
    337 
     327       
    338328        bitmap_block->dirty = true;
    339 
     329       
    340330        /* Save bitmap */
    341         rc = block_put(bitmap_block);
    342         if (rc != EOK) {
    343                 return rc;
    344         }
    345 
    346         return EOK;
     331        return block_put(bitmap_block);
    347332}
    348333
    349334/** Initialize i-node table in block group.
    350  *
    351  * @param bg_ref        reference to block group
    352  * @return                      error code
     335 *
     336 * @param bg_ref Reference to block group
     337 *
     338 * @return Error code
     339 *
    353340 */
    354341static int ext4_filesystem_init_inode_table(ext4_block_group_ref_t *bg_ref)
    355342{
    356         int rc;
    357 
    358343        ext4_superblock_t *sb = bg_ref->fs->superblock;
    359 
     344       
    360345        uint32_t inode_size = ext4_superblock_get_inode_size(sb);
    361346        uint32_t block_size = ext4_superblock_get_block_size(sb);
    362347        uint32_t inodes_per_block = block_size / inode_size;
    363 
     348       
    364349        uint32_t inodes_in_group =
    365                         ext4_superblock_get_inodes_in_group(sb, bg_ref->index);
    366 
     350            ext4_superblock_get_inodes_in_group(sb, bg_ref->index);
     351       
    367352        uint32_t table_blocks = inodes_in_group / inodes_per_block;
    368 
    369         if (inodes_in_group % inodes_per_block) {
     353       
     354        if (inodes_in_group % inodes_per_block)
    370355                table_blocks++;
    371         }
    372 
     356       
    373357        /* Compute initialization bounds */
    374358        uint32_t first_block = ext4_block_group_get_inode_table_first_block(
    375                         bg_ref->block_group, sb);
    376 
     359            bg_ref->block_group, sb);
     360       
    377361        uint32_t last_block = first_block + table_blocks - 1;
    378 
     362       
    379363        /* Initialization of all itable blocks */
    380364        for (uint32_t fblock = first_block; fblock <= last_block; ++fblock) {
    381365                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 
     366                int rc = block_get(&block, bg_ref->fs->device, fblock,
     367                    BLOCK_FLAGS_NOREAD);
     368                if (rc != EOK)
     369                        return rc;
     370               
    387371                memset(block->data, 0, block_size);
    388372                block->dirty = true;
    389 
     373               
    390374                rc = block_put(block);
    391                 if (rc != EOK) {
    392                         return rc;
    393                 }
    394         }
    395 
     375                if (rc != EOK)
     376                        return rc;
     377        }
     378       
    396379        return EOK;
    397380}
     
    399382/** Get reference to block group specified by index.
    400383 *
    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
     384 * @param fs   Filesystem to find block group on
     385 * @param bgid Index of block group to load
     386 * @param ref  Output pointer for reference
     387 *
     388 * @return Error code
     389 *
    405390 */
    406391int ext4_filesystem_get_block_group_ref(ext4_filesystem_t *fs, uint32_t bgid,
    407392    ext4_block_group_ref_t **ref)
    408393{
    409         int rc;
    410 
    411394        /* Allocate memory for new structure */
    412         ext4_block_group_ref_t *newref = malloc(sizeof(ext4_block_group_ref_t));
    413         if (newref == NULL) {
     395        ext4_block_group_ref_t *newref =
     396            malloc(sizeof(ext4_block_group_ref_t));
     397        if (newref == NULL)
    414398                return ENOMEM;
    415         }
    416 
     399       
    417400        /* 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 
     401        uint32_t descriptors_per_block =
     402            ext4_superblock_get_block_size(fs->superblock) /
     403            ext4_superblock_get_desc_size(fs->superblock);
     404       
    421405        /* 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 
     406        aoff64_t block_id =
     407            ext4_superblock_get_first_data_block(fs->superblock) + 1;
     408       
    424409        /* Find the block containing the descriptor we are looking for */
    425410        block_id += bgid / descriptors_per_block;
    426         uint32_t offset = (bgid % descriptors_per_block) * ext4_superblock_get_desc_size(fs->superblock);
    427 
     411        uint32_t offset = (bgid % descriptors_per_block) *
     412            ext4_superblock_get_desc_size(fs->superblock);
     413       
    428414        /* Load block with descriptors */
    429         rc = block_get(&newref->block, fs->device, block_id, 0);
     415        int rc = block_get(&newref->block, fs->device, block_id, 0);
    430416        if (rc != EOK) {
    431417                free(newref);
    432418                return rc;
    433419        }
    434 
     420       
    435421        /* Inititialize in-memory representation */
    436422        newref->block_group = newref->block->data + offset;
     
    438424        newref->index = bgid;
    439425        newref->dirty = false;
    440 
     426       
    441427        *ref = newref;
    442 
     428       
    443429        if (ext4_block_group_has_flag(newref->block_group,
    444                         EXT4_BLOCK_GROUP_BLOCK_UNINIT)) {
    445 
     430            EXT4_BLOCK_GROUP_BLOCK_UNINIT)) {
    446431                rc = ext4_filesystem_init_block_bitmap(newref);
    447432                if (rc != EOK) {
     
    450435                        return rc;
    451436                }
     437               
    452438                ext4_block_group_clear_flag(newref->block_group,
    453                                 EXT4_BLOCK_GROUP_BLOCK_UNINIT);
    454 
     439                    EXT4_BLOCK_GROUP_BLOCK_UNINIT);
     440               
    455441                newref->dirty = true;
    456442        }
    457 
     443       
    458444        if (ext4_block_group_has_flag(newref->block_group,
    459                         EXT4_BLOCK_GROUP_INODE_UNINIT)) {
    460 
     445            EXT4_BLOCK_GROUP_INODE_UNINIT)) {
    461446                rc = ext4_filesystem_init_inode_bitmap(newref);
    462447                if (rc != EOK) {
     
    465450                        return rc;
    466451                }
    467 
     452               
    468453                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 
     454                    EXT4_BLOCK_GROUP_INODE_UNINIT);
     455               
     456                if (!ext4_block_group_has_flag(newref->block_group,
     457                    EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
    474458                        rc = ext4_filesystem_init_inode_table(newref);
    475                         if (rc != EOK) {
     459                        if (rc != EOK)
    476460                                return rc;
    477                         }
    478 
     461                       
    479462                        ext4_block_group_set_flag(newref->block_group,
    480                                         EXT4_BLOCK_GROUP_ITABLE_ZEROED);
    481 
     463                            EXT4_BLOCK_GROUP_ITABLE_ZEROED);
    482464                }
     465               
    483466                newref->dirty = true;
    484 
    485         }
    486 
     467        }
     468       
    487469        return EOK;
    488470}
     
    492474 * It uses crc functions from Linux kernel implementation.
    493475 *
    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
     476 * @param sb   Superblock
     477 * @param bgid Index of block group in the filesystem
     478 * @param bg   Block group to compute checksum for
     479 *
     480 * @return Checksum value
     481 *
    498482 */
    499483static uint16_t ext4_filesystem_bg_checksum(ext4_superblock_t *sb, uint32_t bgid,
    500                             ext4_block_group_t *bg)
     484    ext4_block_group_t *bg)
    501485{
    502486        /* If checksum not supported, 0 will be returned */
    503487        uint16_t crc = 0;
    504 
     488       
    505489        /* 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 
     490        if (ext4_superblock_has_feature_read_only(sb,
     491            EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
    508492                void *base = bg;
    509493                void *checksum = &bg->checksum;
    510 
    511                 uint32_t offset = (uint32_t)(checksum - base);
    512 
     494               
     495                uint32_t offset = (uint32_t) (checksum - base);
     496               
    513497                /* Convert block group index to little endian */
    514498                uint32_t le_group = host2uint32_t_le(bgid);
    515 
     499               
    516500                /* Initialization */
    517501                crc = crc16(~0, sb->uuid, sizeof(sb->uuid));
    518 
     502               
    519503                /* Include index of block group */
    520                 crc = crc16(crc, (uint8_t *)&le_group, sizeof(le_group));
    521 
     504                crc = crc16(crc, (uint8_t *) &le_group, sizeof(le_group));
     505               
    522506                /* Compute crc from the first part (stop before checksum field) */
    523                 crc = crc16(crc, (uint8_t *)bg, offset);
    524 
     507                crc = crc16(crc, (uint8_t *) bg, offset);
     508               
    525509                /* Skip checksum */
    526510                offset += sizeof(bg->checksum);
    527 
     511               
    528512                /* 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 
     513                if ((ext4_superblock_has_feature_incompatible(sb,
     514                    EXT4_FEATURE_INCOMPAT_64BIT)) &&
     515                    (offset < ext4_superblock_get_desc_size(sb)))
     516                        crc = crc16(crc, ((uint8_t *) bg) + offset,
     517                            ext4_superblock_get_desc_size(sb) - offset);
     518        }
     519       
    536520        return crc;
    537 
    538521}
    539522
    540523/** Put reference to block group.
    541524 *
    542  * @oaram ref           pointer for reference to be put back
    543  * @return                      error code
     525 * @oaram ref Pointer for reference to be put back
     526 *
     527 * @return Error code
     528 *
    544529 */
    545530int ext4_filesystem_put_block_group_ref(ext4_block_group_ref_t *ref)
    546531{
    547         int rc;
    548 
    549532        /* Check if reference modified */
    550533        if (ref->dirty) {
    551 
    552534                /* Compute new checksum of block group */
    553                 uint16_t checksum = ext4_filesystem_bg_checksum(
    554                                 ref->fs->superblock, ref->index, ref->block_group);
     535                uint16_t checksum =
     536                    ext4_filesystem_bg_checksum(ref->fs->superblock, ref->index,
     537                    ref->block_group);
    555538                ext4_block_group_set_checksum(ref->block_group, checksum);
    556 
     539               
    557540                /* Mark block dirty for writing changes to physical device */
    558541                ref->block->dirty = true;
    559542        }
    560 
     543       
    561544        /* Put back block, that contains block group descriptor */
    562         rc = block_put(ref->block);
     545        int rc = block_put(ref->block);
    563546        free(ref);
    564 
     547       
    565548        return rc;
    566549}
     
    568551/** Get reference to i-node specified by index.
    569552 *
    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
     553 * @param fs    Filesystem to find i-node on
     554 * @param index Index of i-node to load
     555 * @oaram ref   Output pointer for reference
     556 *
     557 * @return Error code
     558 *
    574559 */
    575560int ext4_filesystem_get_inode_ref(ext4_filesystem_t *fs, uint32_t index,
    576561    ext4_inode_ref_t **ref)
    577562{
    578         int rc;
    579 
    580563        /* Allocate memory for new structure */
    581         ext4_inode_ref_t *newref = malloc(sizeof(ext4_inode_ref_t));
    582         if (newref == NULL) {
     564        ext4_inode_ref_t *newref =
     565            malloc(sizeof(ext4_inode_ref_t));
     566        if (newref == NULL)
    583567                return ENOMEM;
    584         }
    585 
     568       
    586569        /* Compute number of i-nodes, that fits in one data block */
    587570        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
     571            ext4_superblock_get_inodes_per_group(fs->superblock);
     572       
     573        /*
     574         * Inode numbers are 1-based, but it is simpler to work with 0-based
    591575         * when computing indices
    592576         */
     
    594578        uint32_t block_group = index / inodes_per_group;
    595579        uint32_t offset_in_group = index % inodes_per_group;
    596 
     580       
    597581        /* Load block group, where i-node is located */
    598582        ext4_block_group_ref_t *bg_ref;
    599         rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
     583        int rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
    600584        if (rc != EOK) {
    601585                free(newref);
    602586                return rc;
    603587        }
    604 
     588       
    605589        /* 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 
     590        uint32_t inode_table_start =
     591            ext4_block_group_get_inode_table_first_block(bg_ref->block_group,
     592            fs->superblock);
     593       
    609594        /* Put back block group reference (not needed more) */
    610595        rc = ext4_filesystem_put_block_group_ref(bg_ref);
     
    613598                return rc;
    614599        }
    615 
     600       
    616601        /* Compute position of i-node in the block group */
    617602        uint16_t inode_size = ext4_superblock_get_inode_size(fs->superblock);
    618603        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    619604        uint32_t byte_offset_in_group = offset_in_group * inode_size;
    620 
     605       
    621606        /* Compute block address */
    622607        aoff64_t block_id = inode_table_start + (byte_offset_in_group / block_size);
     
    626611                return rc;
    627612        }
    628 
     613       
    629614        /* Compute position of i-node in the data block */
    630615        uint32_t offset_in_block = byte_offset_in_group % block_size;
    631616        newref->inode = newref->block->data + offset_in_block;
    632 
     617       
    633618        /* We need to store the original value of index in the reference */
    634619        newref->index = index + 1;
    635620        newref->fs = fs;
    636621        newref->dirty = false;
    637 
     622       
    638623        *ref = newref;
    639 
     624       
    640625        return EOK;
    641626}
     
    643628/** Put reference to i-node.
    644629 *
    645  * @param ref           pointer for reference to be put back
    646  * @return                      error code
     630 * @param ref Pointer for reference to be put back
     631 *
     632 * @return Error code
     633 *
    647634 */
    648635int ext4_filesystem_put_inode_ref(ext4_inode_ref_t *ref)
    649636{
    650         int rc;
    651 
    652637        /* Check if reference modified */
    653638        if (ref->dirty) {
    654 
    655639                /* Mark block dirty for writing changes to physical device */
    656640                ref->block->dirty = true;
    657641        }
    658 
     642       
    659643        /* Put back block, that contains i-node */
    660         rc = block_put(ref->block);
     644        int rc = block_put(ref->block);
    661645        free(ref);
    662 
     646       
    663647        return rc;
    664648}
     
    666650/** Allocate new i-node in the filesystem.
    667651 *
    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
     652 * @param fs        Filesystem to allocated i-node on
     653 * @param inode_ref Output pointer to return reference to allocated i-node
     654 * @param flags     Flags to be set for newly created i-node
     655 *
     656 * @return Error code
     657 *
    672658 */
    673659int ext4_filesystem_alloc_inode(ext4_filesystem_t *fs,
    674                 ext4_inode_ref_t **inode_ref, int flags)
    675 {
    676         int rc;
    677 
     660    ext4_inode_ref_t **inode_ref, int flags)
     661{
    678662        /* Check if newly allocated i-node will be a directory */
    679663        bool is_dir = false;
    680         if (flags & L_DIRECTORY) {
     664        if (flags & L_DIRECTORY)
    681665                is_dir = true;
    682         }
    683 
     666       
    684667        /* Allocate inode by allocation algorithm */
    685668        uint32_t index;
    686         rc = ext4_ialloc_alloc_inode(fs, &index, is_dir);
    687         if (rc != EOK) {
     669        int rc = ext4_ialloc_alloc_inode(fs, &index, is_dir);
     670        if (rc != EOK)
    688671                return rc;
    689         }
    690 
     672       
    691673        /* Load i-node from on-disk i-node table */
    692674        rc = ext4_filesystem_get_inode_ref(fs, index, inode_ref);
     
    695677                return rc;
    696678        }
    697 
     679       
    698680        /* Initialize i-node */
    699681        ext4_inode_t *inode = (*inode_ref)->inode;
    700 
     682       
    701683        uint16_t mode;
    702684        if (is_dir) {
     
    705687                 * 0777 (octal) == rwxrwxrwx
    706688                 */
     689               
    707690                mode = 0777;
    708691                mode |= EXT4_INODE_MODE_DIRECTORY;
    709692                ext4_inode_set_mode(fs->superblock, inode, mode);
    710                 ext4_inode_set_links_count(inode, 1); /* '.' entry */
     693                ext4_inode_set_links_count(inode, 1);  /* '.' entry */
    711694        } else {
    712695                /*
     
    714697                 * 0666 (octal) == rw-rw-rw-
    715698                 */
    716 
     699               
    717700                mode = 0666;
    718701                mode |= EXT4_INODE_MODE_FILE;
     
    720703                ext4_inode_set_links_count(inode, 0);
    721704        }
    722 
     705       
    723706        ext4_inode_set_uid(inode, 0);
    724707        ext4_inode_set_gid(inode, 0);
     
    731714        ext4_inode_set_flags(inode, 0);
    732715        ext4_inode_set_generation(inode, 0);
    733 
     716       
    734717        /* Reset blocks array */
    735         for (uint32_t i = 0; i < EXT4_INODE_BLOCKS; i++) {
     718        for (uint32_t i = 0; i < EXT4_INODE_BLOCKS; i++)
    736719                inode->blocks[i] = 0;
    737         }
    738 
     720       
    739721        /* Initialize extents if needed */
    740722        if (ext4_superblock_has_feature_incompatible(
    741                         fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
    742 
     723            fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
    743724                ext4_inode_set_flag(inode, EXT4_INODE_FLAG_EXTENTS);
    744 
     725               
    745726                /* Initialize extent root header */
    746727                ext4_extent_header_t *header = ext4_inode_get_extent_header(inode);
     
    749730                ext4_extent_header_set_generation(header, 0);
    750731                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 
     732               
     733                uint16_t max_entries = (EXT4_INODE_BLOCKS * sizeof(uint32_t) -
     734                    sizeof(ext4_extent_header_t)) / sizeof(ext4_extent_t);
     735               
    755736                ext4_extent_header_set_max_entries_count(header, max_entries);
    756737        }
    757 
     738       
    758739        (*inode_ref)->dirty = true;
    759 
     740       
    760741        return EOK;
    761742}
     
    763744/** Release i-node and mark it as free.
    764745 *
    765  * @param inode_ref                     i-node to be released
    766  * @return                                      error code
     746 * @param inode_ref I-node to be released
     747 *
     748 * @return Error code
     749 *
    767750 */
    768751int ext4_filesystem_free_inode(ext4_inode_ref_t *inode_ref)
    769752{
    770         int rc;
    771 
    772753        ext4_filesystem_t *fs = inode_ref->fs;
    773 
     754       
    774755        /* 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 
     756        if ((ext4_superblock_has_feature_incompatible(fs->superblock,
     757            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     758            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
    779759                /* Data structures are released during truncate operation... */
    780760                goto finish;
    781761        }
    782 
     762       
    783763        /* Release all indirect (no data) blocks */
    784 
     764       
    785765        /* 1) Single indirect */
    786766        uint32_t fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0);
    787767        if (fblock != 0) {
    788                 rc = ext4_balloc_free_block(inode_ref, fblock);
    789                 if (rc != EOK) {
    790                         return rc;
    791                 }
    792 
     768                int rc = ext4_balloc_free_block(inode_ref, fblock);
     769                if (rc != EOK)
     770                        return rc;
     771               
    793772                ext4_inode_set_indirect_block(inode_ref->inode, 0, 0);
    794773        }
    795 
     774       
    796775        block_t *block;
    797776        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    798777        uint32_t count = block_size / sizeof(uint32_t);
    799 
     778       
    800779        /* 2) Double indirect */
    801780        fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1);
    802781        if (fblock != 0) {
    803                 rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
    804                 if (rc != EOK) {
    805                         return rc;
    806                 }
    807 
     782                int rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
     783                if (rc != EOK)
     784                        return rc;
     785               
    808786                uint32_t ind_block;
    809787                for (uint32_t offset = 0; offset < count; ++offset) {
    810                         ind_block = uint32_t_le2host(((uint32_t*)block->data)[offset]);
    811 
     788                        ind_block = uint32_t_le2host(((uint32_t *) block->data)[offset]);
     789                       
    812790                        if (ind_block != 0) {
    813791                                rc = ext4_balloc_free_block(inode_ref, ind_block);
     
    818796                        }
    819797                }
    820 
     798               
    821799                block_put(block);
    822800                rc = ext4_balloc_free_block(inode_ref, fblock);
    823                 if (rc != EOK) {
    824                         return rc;
    825                 }
    826 
     801                if (rc != EOK)
     802                        return rc;
     803               
    827804                ext4_inode_set_indirect_block(inode_ref->inode, 1, 0);
    828805        }
    829 
    830 
     806       
    831807        /* 3) Tripple indirect */
    832808        block_t *subblock;
    833809        fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2);
    834810        if (fblock != 0) {
    835                 rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
    836                 if (rc != EOK) {
    837                         return rc;
    838                 }
    839 
     811                int rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
     812                if (rc != EOK)
     813                        return rc;
     814               
    840815                uint32_t ind_block;
    841816                for (uint32_t offset = 0; offset < count; ++offset) {
    842                         ind_block = uint32_t_le2host(((uint32_t*)block->data)[offset]);
    843 
     817                        ind_block = uint32_t_le2host(((uint32_t *) block->data)[offset]);
     818                       
    844819                        if (ind_block != 0) {
    845                                 rc = block_get(&subblock, fs->device, ind_block, BLOCK_FLAGS_NONE);
     820                                rc = block_get(&subblock, fs->device, ind_block,
     821                                    BLOCK_FLAGS_NONE);
    846822                                if (rc != EOK) {
    847823                                        block_put(block);
    848824                                        return rc;
    849825                                }
    850 
     826                               
    851827                                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 
     828                                for (uint32_t suboffset = 0; suboffset < count;
     829                                    ++suboffset) {
     830                                        ind_subblock = uint32_t_le2host(((uint32_t *)
     831                                            subblock->data)[suboffset]);
     832                                       
    855833                                        if (ind_subblock != 0) {
    856834                                                rc = ext4_balloc_free_block(inode_ref, ind_subblock);
     
    861839                                                }
    862840                                        }
    863 
    864841                                }
     842                               
    865843                                block_put(subblock);
    866 
    867844                        }
    868 
     845                       
    869846                        rc = ext4_balloc_free_block(inode_ref, ind_block);
    870847                        if (rc != EOK) {
     
    872849                                return rc;
    873850                        }
    874 
    875 
    876851                }
    877 
     852               
    878853                block_put(block);
    879854                rc = ext4_balloc_free_block(inode_ref, fblock);
    880                 if (rc != EOK) {
    881                         return rc;
    882                 }
    883 
     855                if (rc != EOK)
     856                        return rc;
     857               
    884858                ext4_inode_set_indirect_block(inode_ref->inode, 2, 0);
    885859        }
    886 
     860       
    887861finish:
    888 
    889862        /* Mark inode dirty for writing to the physical device */
    890863        inode_ref->dirty = true;
    891 
     864       
    892865        /* Free block with extended attributes if present */
    893866        uint32_t xattr_block = ext4_inode_get_file_acl(
    894                         inode_ref->inode, fs->superblock);
     867            inode_ref->inode, fs->superblock);
    895868        if (xattr_block) {
    896                 rc = ext4_balloc_free_block(inode_ref, xattr_block);
    897                 if (rc != EOK) {
    898                         return rc;
    899                 }
    900 
     869                int rc = ext4_balloc_free_block(inode_ref, xattr_block);
     870                if (rc != EOK)
     871                        return rc;
     872               
    901873                ext4_inode_set_file_acl(inode_ref->inode, fs->superblock, 0);
    902874        }
    903 
     875       
    904876        /* Free inode by allocator */
     877        int rc;
    905878        if (ext4_inode_is_type(fs->superblock, inode_ref->inode,
    906                         EXT4_INODE_MODE_DIRECTORY)) {
     879            EXT4_INODE_MODE_DIRECTORY))
    907880                rc = ext4_ialloc_free_inode(fs, inode_ref->index, true);
    908         } else {
     881        else
    909882                rc = ext4_ialloc_free_inode(fs, inode_ref->index, false);
    910         }
    911         if (rc != EOK) {
    912                 return rc;
    913         }
    914 
    915         return EOK;
     883       
     884        return rc;
    916885}
    917886
    918887/** Truncate i-node data blocks.
    919888 *
    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 
     889 * @param inode_ref I-node to be truncated
     890 * @param new_size  New size of inode (must be < current size)
     891 *
     892 * @return Error code
     893 *
     894 */
     895int ext4_filesystem_truncate_inode(ext4_inode_ref_t *inode_ref,
     896    aoff64_t new_size)
     897{
    929898        ext4_superblock_t *sb = inode_ref->fs->superblock;
    930 
     899       
    931900        /* Check flags, if i-node can be truncated */
    932         if (! ext4_inode_can_truncate(sb, inode_ref->inode)) {
     901        if (!ext4_inode_can_truncate(sb, inode_ref->inode))
    933902                return EINVAL;
    934         }
    935 
     903       
    936904        /* If sizes are equal, nothing has to be done. */
    937905        aoff64_t old_size = ext4_inode_get_size(sb, inode_ref->inode);
    938         if (old_size == new_size) {
     906        if (old_size == new_size)
    939907                return EOK;
    940         }
    941 
     908       
    942909        /* It's not suppported to make the larger file by truncate operation */
    943         if (old_size < new_size) {
     910        if (old_size < new_size)
    944911                return EINVAL;
    945         }
    946 
     912       
    947913        /* Compute how many blocks will be released */
    948914        aoff64_t size_diff = old_size - new_size;
    949915        uint32_t block_size  = ext4_superblock_get_block_size(sb);
    950916        uint32_t diff_blocks_count = size_diff / block_size;
    951         if (size_diff % block_size != 0) {
     917        if (size_diff % block_size != 0)
    952918                diff_blocks_count++;
    953         }
    954 
     919       
    955920        uint32_t old_blocks_count = old_size / block_size;
    956         if (old_size % block_size != 0) {
     921        if (old_size % block_size != 0)
    957922                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 
     923       
     924        if ((ext4_superblock_has_feature_incompatible(inode_ref->fs->superblock,
     925            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     926            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
    964927                /* 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                 }
     928                int rc = ext4_extent_release_blocks_from(inode_ref,
     929                    old_blocks_count - diff_blocks_count);
     930                if (rc != EOK)
     931                        return rc;
    971932        } else {
    972 
    973933                /* Release data blocks from the end of file */
    974 
     934               
    975935                /* Starting from 1 because of logical blocks are numbered from 0 */
    976936                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) {
     937                        int rc = ext4_filesystem_release_inode_block(inode_ref,
     938                            old_blocks_count - i);
     939                        if (rc != EOK)
    979940                                return rc;
    980                         }
    981941                }
    982942        }
    983 
     943       
    984944        /* Update i-node */
    985945        ext4_inode_set_size(inode_ref->inode, new_size);
    986946        inode_ref->dirty = true;
    987 
     947       
    988948        return EOK;
    989949}
     
    991951/** Get physical block address by logical index of the block.
    992952 *
    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
     953 * @param inode_ref I-node to read block address from
     954 * @param iblock    Logical index of block
     955 * @param fblock    Output pointer for return physical block address
     956 *
     957 * @return Error code
     958 *
    997959 */
    998960int 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 
     961    aoff64_t iblock, uint32_t *fblock)
     962{
    1003963        ext4_filesystem_t *fs = inode_ref->fs;
    1004 
     964       
    1005965        /* For empty file is situation simple */
    1006966        if (ext4_inode_get_size(fs->superblock, inode_ref->inode) == 0) {
     
    1008968                return EOK;
    1009969        }
    1010 
     970       
    1011971        uint32_t current_block;
    1012 
     972       
    1013973        /* 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 
     974        if ((ext4_superblock_has_feature_incompatible(fs->superblock,
     975            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     976            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
     977                int rc = ext4_extent_find_block(inode_ref, iblock, &current_block);
     978                if (rc != EOK)
     979                        return rc;
     980               
    1023981                *fblock = current_block;
    1024982                return EOK;
    1025 
    1026         }
    1027 
     983        }
     984       
    1028985        ext4_inode_t *inode = inode_ref->inode;
    1029 
     986       
    1030987        /* Direct block are read directly from array in i-node structure */
    1031988        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
    1032                 current_block = ext4_inode_get_direct_block(inode, (uint32_t)iblock);
     989                current_block = ext4_inode_get_direct_block(inode, (uint32_t) iblock);
    1033990                *fblock = current_block;
    1034991                return EOK;
    1035992        }
    1036 
     993       
    1037994        /* Determine indirection level of the target block */
    1038         int level = -1;
    1039         for (int i = 1; i < 4; i++) {
     995        unsigned int level = 0;
     996        for (unsigned int i = 1; i < 4; i++) {
    1040997                if (iblock < fs->inode_block_limits[i]) {
    1041998                        level = i;
     
    10431000                }
    10441001        }
    1045 
    1046         if (level == -1) {
     1002       
     1003        if (level == 0)
    10471004                return EIO;
    1048         }
    1049 
     1005       
    10501006        /* 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 
     1007        aoff64_t block_offset_in_level =
     1008            iblock - fs->inode_block_limits[level - 1];
     1009        current_block = ext4_inode_get_indirect_block(inode, level - 1);
     1010        uint32_t offset_in_block =
     1011            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1012       
    10551013        /* Sparse file */
    10561014        if (current_block == 0) {
     
    10581016                return EOK;
    10591017        }
    1060 
     1018       
    10611019        block_t *block;
    1062 
    1063         /* Navigate through other levels, until we find the block number
     1020       
     1021        /*
     1022         * Navigate through other levels, until we find the block number
    10641023         * or find null reference meaning we are dealing with sparse file
    10651024         */
    10661025        while (level > 0) {
    1067 
    10681026                /* Load indirect block */
    1069                 rc = block_get(&block, fs->device, current_block, 0);
    1070                 if (rc != EOK) {
    1071                         return rc;
    1072                 }
    1073 
     1027                int rc = block_get(&block, fs->device, current_block, 0);
     1028                if (rc != EOK)
     1029                        return rc;
     1030               
    10741031                /* Read block address from indirect block */
    1075                 current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]);
    1076 
     1032                current_block =
     1033                    uint32_t_le2host(((uint32_t *) block->data)[offset_in_block]);
     1034               
    10771035                /* Put back indirect block untouched */
    10781036                rc = block_put(block);
    1079                 if (rc != EOK) {
    1080                         return rc;
    1081                 }
    1082 
     1037                if (rc != EOK)
     1038                        return rc;
     1039               
    10831040                /* Check for sparse file */
    10841041                if (current_block == 0) {
     
    10861043                        return EOK;
    10871044                }
    1088 
     1045               
    10891046                /* Jump to the next level */
    1090                 level -= 1;
    1091 
     1047                level--;
     1048               
    10921049                /* Termination condition - we have address of data block loaded */
    1093                 if (level == 0) {
     1050                if (level == 0)
    10941051                        break;
    1095                 }
    1096 
     1052               
    10971053                /* Visit the next level */
    10981054                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 
     1055                offset_in_block =
     1056                    block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1057        }
     1058       
    11021059        *fblock = current_block;
    1103 
     1060       
    11041061        return EOK;
    11051062}
     
    11071064/** Set physical block address for the block logical address into the i-node.
    11081065 *
    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
     1066 * @param inode_ref I-node to set block address to
     1067 * @param iblock    Logical index of block
     1068 * @param fblock    Physical block address
     1069 *
     1070 * @return Error code
     1071 *
    11131072 */
    11141073int 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 
     1074    aoff64_t iblock, uint32_t fblock)
     1075{
    11191076        ext4_filesystem_t *fs = inode_ref->fs;
    1120 
     1077       
    11211078        /* 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 !!! */
     1079        if ((ext4_superblock_has_feature_compatible(fs->superblock,
     1080            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     1081            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
     1082                /* Not reachable */
    11251083                return ENOTSUP;
    11261084        }
    1127 
     1085       
    11281086        /* Handle simple case when we are dealing with direct reference */
    11291087        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
    1130                 ext4_inode_set_direct_block(inode_ref->inode, (uint32_t)iblock, fblock);
     1088                ext4_inode_set_direct_block(inode_ref->inode, (uint32_t) iblock, fblock);
    11311089                inode_ref->dirty = true;
     1090               
    11321091                return EOK;
    11331092        }
    1134 
     1093       
    11351094        /* Determine the indirection level needed to get the desired block */
    1136         int level = -1;
    1137         for (int i = 1; i < 4; i++) {
     1095        unsigned int level = 0;
     1096        for (unsigned int i = 1; i < 4; i++) {
    11381097                if (iblock < fs->inode_block_limits[i]) {
    11391098                        level = i;
     
    11411100                }
    11421101        }
    1143 
    1144         if (level == -1) {
     1102       
     1103        if (level == 0)
    11451104                return EIO;
    1146         }
    1147 
     1105       
    11481106        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    1149 
     1107       
    11501108        /* 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 
     1109        aoff64_t block_offset_in_level =
     1110            iblock - fs->inode_block_limits[level - 1];
     1111        uint32_t current_block =
     1112            ext4_inode_get_indirect_block(inode_ref->inode, level - 1);
     1113        uint32_t offset_in_block =
     1114            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1115       
    11551116        uint32_t new_block_addr;
    1156         block_t *block, *new_block;
    1157 
     1117        block_t *block;
     1118        block_t *new_block;
     1119       
    11581120        /* Is needed to allocate indirect block on the i-node level */
    11591121        if (current_block == 0) {
    1160 
    11611122                /* Allocate new indirect block */
    1162                 rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
    1163                 if (rc != EOK) {
    1164                         return rc;
    1165                 }
    1166 
     1123                int rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
     1124                if (rc != EOK)
     1125                        return rc;
     1126               
    11671127                /* Update i-node */
    1168                 ext4_inode_set_indirect_block(inode_ref->inode, level - 1, new_block_addr);
     1128                ext4_inode_set_indirect_block(inode_ref->inode, level - 1,
     1129                    new_block_addr);
    11691130                inode_ref->dirty = true;
    1170 
     1131               
    11711132                /* Load newly allocated block */
    1172                 rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD);
     1133                rc = block_get(&new_block, fs->device, new_block_addr,
     1134                    BLOCK_FLAGS_NOREAD);
    11731135                if (rc != EOK) {
    11741136                        ext4_balloc_free_block(inode_ref, new_block_addr);
    11751137                        return rc;
    11761138                }
    1177 
     1139               
    11781140                /* Initialize new block */
    11791141                memset(new_block->data, 0, block_size);
    11801142                new_block->dirty = true;
    1181 
     1143               
    11821144                /* Put back the allocated block */
    11831145                rc = block_put(new_block);
    1184                 if (rc != EOK) {
    1185                         return rc;
    1186                 }
    1187 
     1146                if (rc != EOK)
     1147                        return rc;
     1148               
    11881149                current_block = new_block_addr;
    11891150        }
    1190 
    1191         /* Navigate through other levels, until we find the block number
     1151       
     1152        /*
     1153         * Navigate through other levels, until we find the block number
    11921154         * or find null reference meaning we are dealing with sparse file
    11931155         */
    11941156        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 
     1157                int rc = block_get(&block, fs->device, current_block, 0);
     1158                if (rc != EOK)
     1159                        return rc;
     1160               
     1161                current_block =
     1162                    uint32_t_le2host(((uint32_t *) block->data)[offset_in_block]);
     1163               
    12031164                if ((level > 1) && (current_block == 0)) {
    1204 
    12051165                        /* Allocate new block */
    12061166                        rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
     
    12091169                                return rc;
    12101170                        }
    1211 
     1171                       
    12121172                        /* Load newly allocated block */
    1213                         rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD);
     1173                        rc = block_get(&new_block, fs->device, new_block_addr,
     1174                            BLOCK_FLAGS_NOREAD);
    12141175                        if (rc != EOK) {
    12151176                                block_put(block);
    12161177                                return rc;
    12171178                        }
    1218 
     1179                       
    12191180                        /* Initialize allocated block */
    12201181                        memset(new_block->data, 0, block_size);
    12211182                        new_block->dirty = true;
    1222 
     1183                       
    12231184                        rc = block_put(new_block);
    12241185                        if (rc != EOK) {
     
    12261187                                return rc;
    12271188                        }
    1228 
     1189                       
    12291190                        /* Write block address to the parent */
    1230                         ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(new_block_addr);
     1191                        ((uint32_t *) block->data)[offset_in_block] =
     1192                            host2uint32_t_le(new_block_addr);
    12311193                        block->dirty = true;
    12321194                        current_block = new_block_addr;
    12331195                }
    1234 
     1196               
    12351197                /* Will be finished, write the fblock address */
    12361198                if (level == 1) {
    1237                         ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(fblock);
     1199                        ((uint32_t *) block->data)[offset_in_block] =
     1200                            host2uint32_t_le(fblock);
    12381201                        block->dirty = true;
    12391202                }
    1240 
     1203               
    12411204                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
     1205                if (rc != EOK)
     1206                        return rc;
     1207               
     1208                level--;
     1209               
     1210                /*
     1211                 * If we are on the last level, break here as
    12491212                 * there is no next level to visit
    12501213                 */
    1251                 if (level == 0) {
     1214                if (level == 0)
    12521215                        break;
    1253                 }
    1254 
     1216               
    12551217                /* Visit the next level */
    12561218                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 
     1219                offset_in_block =
     1220                    block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1221        }
     1222       
    12601223        return EOK;
    12611224}
     
    12631226/** Release data block from i-node
    12641227 *
    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 
     1228 * @param inode_ref I-node to release block from
     1229 * @param iblock    Logical block to be released
     1230 *
     1231 * @return Error code
     1232 *
     1233 */
     1234int ext4_filesystem_release_inode_block(ext4_inode_ref_t *inode_ref,
     1235    uint32_t iblock)
     1236{
    12741237        uint32_t fblock;
    1275 
     1238       
    12761239        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 
     1240       
     1241        /* Extents are handled otherwise = there is not support in this function */
     1242        assert(!(ext4_superblock_has_feature_incompatible(fs->superblock,
     1243            EXT4_FEATURE_INCOMPAT_EXTENTS) &&
     1244            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))));
     1245       
    12831246        ext4_inode_t *inode = inode_ref->inode;
    1284 
     1247       
    12851248        /* Handle simple case when we are dealing with direct reference */
    12861249        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
    12871250                fblock = ext4_inode_get_direct_block(inode, iblock);
     1251               
    12881252                /* Sparse file */
    1289                 if (fblock == 0) {
     1253                if (fblock == 0)
    12901254                        return EOK;
    1291                 }
    1292 
     1255               
    12931256                ext4_inode_set_direct_block(inode, iblock, 0);
    12941257                return ext4_balloc_free_block(inode_ref, fblock);
    12951258        }
    1296 
    1297 
     1259       
    12981260        /* Determine the indirection level needed to get the desired block */
    1299         int level = -1;
    1300         for (int i = 1; i < 4; i++) {
     1261        unsigned int level = 0;
     1262        for (unsigned int i = 1; i < 4; i++) {
    13011263                if (iblock < fs->inode_block_limits[i]) {
    13021264                        level = i;
     
    13041266                }
    13051267        }
    1306 
    1307         if (level == -1) {
     1268       
     1269        if (level == 0)
    13081270                return EIO;
    1309         }
    1310 
     1271       
    13111272        /* 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
     1273        aoff64_t block_offset_in_level =
     1274            iblock - fs->inode_block_limits[level - 1];
     1275        uint32_t current_block =
     1276            ext4_inode_get_indirect_block(inode, level - 1);
     1277        uint32_t offset_in_block =
     1278            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1279       
     1280        /*
     1281         * Navigate through other levels, until we find the block number
    13171282         * or find null reference meaning we are dealing with sparse file
    13181283         */
    13191284        block_t *block;
    13201285        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 
     1286                int rc = block_get(&block, fs->device, current_block, 0);
     1287                if (rc != EOK)
     1288                        return rc;
     1289               
     1290                current_block =
     1291                    uint32_t_le2host(((uint32_t *) block->data)[offset_in_block]);
     1292               
    13281293                /* Set zero if physical data block address found */
    13291294                if (level == 1) {
    1330                         ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(0);
     1295                        ((uint32_t *) block->data)[offset_in_block] =
     1296                            host2uint32_t_le(0);
    13311297                        block->dirty = true;
    13321298                }
    1333 
     1299               
    13341300                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
     1301                if (rc != EOK)
     1302                        return rc;
     1303               
     1304                level--;
     1305               
     1306                /*
     1307                 * If we are on the last level, break here as
    13421308                 * there is no next level to visit
    13431309                 */
    1344                 if (level == 0) {
     1310                if (level == 0)
    13451311                        break;
    1346                 }
    1347 
     1312               
    13481313                /* Visit the next level */
    13491314                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 
     1315                offset_in_block =
     1316                    block_offset_in_level / fs->inode_blocks_per_level[level - 1];
     1317        }
     1318       
    13531319        fblock = current_block;
    1354 
    1355         if (fblock == 0) {
     1320        if (fblock == 0)
    13561321                return EOK;
    1357         }
    1358 
     1322       
    13591323        /* Physical block is not referenced, it can be released */
    1360 
    13611324        return ext4_balloc_free_block(inode_ref, fblock);
    1362 
    13631325}
    13641326
    13651327/** Append following logical block to the i-node.
    13661328 *
    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
     1329 * @param inode_ref I-node to append block to
     1330 * @param fblock    Output physical block address of newly allocated block
     1331 * @param iblock    Output logical number of newly allocated block
     1332 *
     1333 * @return Error code
     1334 *
    13711335 */
    13721336int ext4_filesystem_append_inode_block(ext4_inode_ref_t *inode_ref,
    1373                 uint32_t *fblock, uint32_t *iblock)
    1374 {
    1375         int rc;
    1376 
     1337    uint32_t *fblock, uint32_t *iblock)
     1338{
    13771339        /* 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 
     1340        if ((ext4_superblock_has_feature_incompatible(inode_ref->fs->superblock,
     1341            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     1342            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)))
    13821343                return ext4_extent_append_block(inode_ref, iblock, fblock, true);
    1383 
    1384         }
    1385 
     1344       
    13861345        ext4_superblock_t *sb = inode_ref->fs->superblock;
    1387 
     1346       
    13881347        /* Compute next block index and allocate data block */
    13891348        uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
    13901349        uint32_t block_size = ext4_superblock_get_block_size(sb);
    1391 
     1350       
    13921351        /* Align size i-node size */
    1393         if ((inode_size % block_size) != 0) {
     1352        if ((inode_size % block_size) != 0)
    13941353                inode_size += block_size - (inode_size % block_size);
    1395         }
    1396 
     1354       
    13971355        /* Logical blocks are numbered from 0 */
    13981356        uint32_t new_block_idx = inode_size / block_size;
    1399 
     1357       
    14001358        /* Allocate new physical block */
    14011359        uint32_t phys_block;
    1402         rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
    1403         if (rc != EOK) {
     1360        int rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
     1361        if (rc != EOK)
    14041362                return rc;
    1405         }
    1406 
     1363       
    14071364        /* Add physical block address to the i-node */
    1408         rc = ext4_filesystem_set_inode_data_block_index(inode_ref, new_block_idx, phys_block);
     1365        rc = ext4_filesystem_set_inode_data_block_index(inode_ref,
     1366            new_block_idx, phys_block);
    14091367        if (rc != EOK) {
    14101368                ext4_balloc_free_block(inode_ref, phys_block);
    14111369                return rc;
    14121370        }
    1413 
     1371       
    14141372        /* Update i-node */
    14151373        ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
    14161374        inode_ref->dirty = true;
    1417 
     1375       
    14181376        *fblock = phys_block;
    14191377        *iblock = new_block_idx;
    1420 
     1378       
    14211379        return EOK;
    14221380}
     
    14241382/**
    14251383 * @}
    1426  */ 
     1384 */
Note: See TracChangeset for help on using the changeset viewer.