Changeset 38542dc in mainline for uspace/lib/ext4/libext4_filesystem.c


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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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 */
Note: See TracChangeset for help on using the changeset viewer.