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

Changeset 4cdac68 in mainline


Ignore:
Timestamp:
2012-07-20T20:27:31Z (9 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master
Children:
b828907
Parents:
865a4bf
Message:

debugged initialization of block group structures

Location:
uspace/lib/ext4
Files:
5 edited

Legend:

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

    r865a4bf r4cdac68  
    4040#include "libext4.h"
    4141
    42 /** Convert block address to relative index in block group.
    43  *
    44  * @param sb                    superblock pointer
    45  * @param block_addr    block number to convert
    46  * @return                              relative number of block
    47  */
    48 static uint32_t ext4_balloc_blockaddr2_index_in_group(ext4_superblock_t *sb,
    49                 uint32_t block_addr)
    50 {
    51         uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
    52         uint32_t first_block = ext4_superblock_get_first_data_block(sb);
    53 
    54         /* First block == 0 or 1 */
    55         if (first_block == 0) {
    56                 return block_addr % blocks_per_group;
    57         } else {
    58                 return (block_addr - 1) % blocks_per_group;
    59         }
    60 }
    61 
    62 /** Convert relative block number to absolute.
    63  *
    64  * @param sb                    superblock pointer
    65  * @param index                 relative index of block in group
    66  * @param bgid                  index of block group
    67  * @return                              absolute number of block
    68  */
    69 static uint32_t ext4_balloc_index_in_group2blockaddr(ext4_superblock_t *sb,
    70                 uint32_t index, uint32_t bgid)
    71 {
    72         uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
    73 
    74         if (ext4_superblock_get_first_data_block(sb) == 0) {
    75                 return bgid * blocks_per_group + index;
    76         } else {
    77                 return bgid * blocks_per_group + index + 1;
    78         }
    79 
    80 }
    81 
    8242/** Compute number of block group from block address.
    8343 *
     
    11676        /* Compute indexes */
    11777        uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, block_addr);
    118         uint32_t index_in_group = ext4_balloc_blockaddr2_index_in_group(sb, block_addr);
     78        uint32_t index_in_group =
     79                        ext4_filesystem_blockaddr2_index_in_group(sb, block_addr);
    11980
    12081        /* Load block group reference */
     
    213174
    214175        uint32_t index_in_group_first =
    215                         ext4_balloc_blockaddr2_index_in_group(sb, first);
     176                        ext4_filesystem_blockaddr2_index_in_group(sb, first);
    216177
    217178
     
    278239 * @return                      absolute block index of first block
    279240 */
    280 static uint32_t ext4_balloc_get_first_data_block_in_group(
     241uint32_t ext4_balloc_get_first_data_block_in_group(
    281242                ext4_superblock_t *sb, ext4_block_group_ref_t *bg_ref)
    282243{
     
    415376        /* Load block group number for goal and relative index */
    416377        uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, goal);
    417         uint32_t index_in_group = ext4_balloc_blockaddr2_index_in_group(sb, goal);
     378        uint32_t index_in_group =
     379                        ext4_filesystem_blockaddr2_index_in_group(sb, goal);
    418380
    419381
     
    430392                        ext4_balloc_get_first_data_block_in_group(sb, bg_ref);
    431393
    432         uint32_t first_in_group_index = ext4_balloc_blockaddr2_index_in_group(
     394        uint32_t first_in_group_index = ext4_filesystem_blockaddr2_index_in_group(
    433395                        sb, first_in_group);
    434396
     
    460422                }
    461423
    462                 allocated_block = ext4_balloc_index_in_group2blockaddr(
     424                allocated_block = ext4_filesystem_index_in_group2blockaddr(
    463425                                                        sb, index_in_group, block_group);
    464426
     
    486448                        }
    487449
    488                         allocated_block = ext4_balloc_index_in_group2blockaddr(
     450                        allocated_block = ext4_filesystem_index_in_group2blockaddr(
    489451                                        sb, tmp_idx, block_group);
    490452
     
    504466                }
    505467
    506                 allocated_block = ext4_balloc_index_in_group2blockaddr(
     468                allocated_block = ext4_filesystem_index_in_group2blockaddr(
    507469                                sb, rel_block_idx, block_group);
    508470
     
    520482                }
    521483
    522                 allocated_block = ext4_balloc_index_in_group2blockaddr(
     484                allocated_block = ext4_filesystem_index_in_group2blockaddr(
    523485                                sb, rel_block_idx, block_group);
    524486
     
    557519                first_in_group = ext4_balloc_get_first_data_block_in_group(
    558520                                sb, bg_ref);
    559                 index_in_group = ext4_balloc_blockaddr2_index_in_group(sb,
     521                index_in_group = ext4_filesystem_blockaddr2_index_in_group(sb,
    560522                                                first_in_group);
    561523                blocks_in_group = ext4_superblock_get_blocks_in_group(sb, bgid);
    562524
    563                 first_in_group_index = ext4_balloc_blockaddr2_index_in_group(
     525                first_in_group_index = ext4_filesystem_blockaddr2_index_in_group(
    564526                        sb, first_in_group);
    565527
     
    578540                        }
    579541
    580                         allocated_block = ext4_balloc_index_in_group2blockaddr(
     542                        allocated_block = ext4_filesystem_index_in_group2blockaddr(
    581543                                        sb, rel_block_idx, bgid);
    582544
     
    594556                        }
    595557
    596                         allocated_block = ext4_balloc_index_in_group2blockaddr(
     558                        allocated_block = ext4_filesystem_index_in_group2blockaddr(
    597559                                        sb, rel_block_idx, bgid);
    598560
     
    656618        /* Compute indexes */
    657619        uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, fblock);
    658         uint32_t index_in_group = ext4_balloc_blockaddr2_index_in_group(sb, fblock);
     620        uint32_t index_in_group =
     621                        ext4_filesystem_blockaddr2_index_in_group(sb, fblock);
    659622
    660623        /* Load block group reference */
  • uspace/lib/ext4/libext4_balloc.h

    r865a4bf r4cdac68  
    4040extern int ext4_balloc_free_blocks(ext4_inode_ref_t *,
    4141                uint32_t , uint32_t);
     42extern uint32_t ext4_balloc_get_first_data_block_in_group(
     43                ext4_superblock_t *, ext4_block_group_ref_t *);
    4244extern int ext4_balloc_alloc_block(ext4_inode_ref_t *, uint32_t *);
    4345extern int ext4_balloc_try_alloc_block(ext4_inode_ref_t *, uint32_t, bool *);
  • uspace/lib/ext4/libext4_filesystem.c

    r865a4bf r4cdac68  
    7878
    7979        /* Initialize block caching by libblock */
    80         rc = block_cache_init(service_id, block_size, 0, CACHE_MODE_WT);
     80        rc = block_cache_init(service_id, block_size, 0, CACHE_MODE_WB);
    8181        if (rc != EOK) {
    8282                block_fini(fs->device);
     
    104104                block_cache_fini(fs->device);
    105105                block_fini(fs->device);
    106                 EXT4FS_DBG("invalid state error");
     106                EXT4FS_DBG("Unable to mount: Invalid state error");
    107107                return ENOTSUP;
    108108        }
     
    117117                return rc;
    118118        }
     119
     120        uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock);
     121        ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1);
    119122
    120123        return EOK;
     
    189192        incompatible_features &= ~EXT4_FEATURE_INCOMPAT_SUPP;
    190193        if (incompatible_features > 0) {
     194                EXT4FS_DBG("Not supported incompatible features");
    191195                return ENOTSUP;
    192196        }
     
    199203        compatible_read_only &= ~EXT4_FEATURE_RO_COMPAT_SUPP;
    200204        if (compatible_read_only > 0) {
     205                EXT4FS_DBG("Not supported readonly features - mounting READ-ONLY");
    201206                *read_only = true;
    202207                return EOK;
     208        }
     209
     210        return EOK;
     211}
     212
     213
     214/** Convert block address to relative index in block group.
     215 *
     216 * @param sb                    superblock pointer
     217 * @param block_addr    block number to convert
     218 * @return                              relative number of block
     219 */
     220uint32_t ext4_filesystem_blockaddr2_index_in_group(ext4_superblock_t *sb,
     221                uint32_t block_addr)
     222{
     223        uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
     224        uint32_t first_block = ext4_superblock_get_first_data_block(sb);
     225
     226        /* First block == 0 or 1 */
     227        if (first_block == 0) {
     228                return block_addr % blocks_per_group;
     229        } else {
     230                return (block_addr - 1) % blocks_per_group;
     231        }
     232}
     233
     234
     235/** Convert relative block address in group to absolute address.
     236 *
     237 * @param sb                    superblock pointer
     238 * @param block_addr    block number to convert
     239 * @return                              absolute block address
     240 */
     241uint32_t ext4_filesystem_index_in_group2blockaddr(ext4_superblock_t *sb,
     242                uint32_t index, uint32_t bgid)
     243{
     244        uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
     245
     246        if (ext4_superblock_get_first_data_block(sb) == 0) {
     247                return bgid * blocks_per_group + index;
     248        } else {
     249                return bgid * blocks_per_group + index + 1;
     250        }
     251
     252}
     253
     254/** Initialize block bitmap in block group.
     255 *
     256 * @param bg_ref        reference to block group
     257 * @return                      error code
     258 */
     259static int ext4_filesystem_init_block_bitmap(ext4_block_group_ref_t *bg_ref)
     260{
     261        int rc;
     262
     263        /* Load bitmap */
     264        uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
     265                        bg_ref->block_group, bg_ref->fs->superblock);
     266        block_t *bitmap_block;
     267
     268        rc = block_get(&bitmap_block, bg_ref->fs->device,
     269                        bitmap_block_addr, BLOCK_FLAGS_NOREAD);
     270        if (rc != EOK) {
     271                return rc;
     272        }
     273
     274        uint8_t *bitmap = bitmap_block->data;
     275
     276        /* Initialize all bitmap bits to zero */
     277        uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock);
     278        memset(bitmap, 0, block_size);
     279
     280        /* Determine first block and first data block in group */
     281        uint32_t first_idx = 0;
     282
     283        uint32_t first_data = ext4_balloc_get_first_data_block_in_group(
     284                        bg_ref->fs->superblock, bg_ref);
     285        uint32_t first_data_idx = ext4_filesystem_blockaddr2_index_in_group(
     286                        bg_ref->fs->superblock, first_data);
     287
     288        /* Set bits from to first block to first data block - 1 to one (allocated) */
     289        for (uint32_t block = first_idx; block < first_data_idx; ++block) {
     290                ext4_bitmap_set_bit(bitmap, block);
     291        }
     292
     293        bitmap_block->dirty = true;
     294
     295        /* Save bitmap */
     296        rc = block_put(bitmap_block);
     297        if (rc != EOK) {
     298                return rc;
     299        }
     300
     301        return EOK;
     302}
     303
     304/** Initialize i-node bitmap in block group.
     305 *
     306 * @param bg_ref        reference to block group
     307 * @return                      error code
     308 */
     309static int ext4_filesystem_init_inode_bitmap(ext4_block_group_ref_t *bg_ref)
     310{
     311        int rc;
     312
     313        /* Load bitmap */
     314        uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
     315                        bg_ref->block_group, bg_ref->fs->superblock);
     316        block_t *bitmap_block;
     317
     318        rc = block_get(&bitmap_block, bg_ref->fs->device,
     319                        bitmap_block_addr, BLOCK_FLAGS_NOREAD);
     320        if (rc != EOK) {
     321                return rc;
     322        }
     323
     324        uint8_t *bitmap = bitmap_block->data;
     325
     326        /* Initialize all bitmap bits to zero */
     327        uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock);
     328        uint32_t inodes_per_group =
     329                        ext4_superblock_get_inodes_per_group(bg_ref->fs->superblock);
     330        memset(bitmap, 0, (inodes_per_group + 7) / 8);
     331
     332        uint32_t start_bit = inodes_per_group;
     333        uint32_t end_bit = block_size * 8;
     334
     335        uint32_t i;
     336        for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++) {
     337                ext4_bitmap_set_bit(bitmap, i);
     338        }
     339
     340        if (i < end_bit) {
     341                memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
     342        }
     343
     344        bitmap_block->dirty = true;
     345
     346        /* Save bitmap */
     347        rc = block_put(bitmap_block);
     348        if (rc != EOK) {
     349                return rc;
     350        }
     351
     352        return EOK;
     353}
     354
     355/** Initialize i-node table in block group.
     356 *
     357 * @param bg_ref        reference to block group
     358 * @return                      error code
     359 */static int ext4_filesystem_init_inode_table(ext4_block_group_ref_t *bg_ref)
     360{
     361        int rc;
     362
     363        ext4_superblock_t *sb = bg_ref->fs->superblock;
     364
     365        uint32_t inode_size = ext4_superblock_get_inode_size(sb);
     366        uint32_t block_size = ext4_superblock_get_block_size(sb);
     367        uint32_t inodes_per_block = block_size / inode_size;
     368
     369        uint32_t inodes_in_group =
     370                        ext4_superblock_get_inodes_in_group(sb, bg_ref->index);
     371
     372        uint32_t table_blocks = inodes_in_group / inodes_per_block;
     373
     374        if (inodes_in_group % inodes_per_block) {
     375                table_blocks++;
     376        }
     377
     378        /* Compute initialization bounds */
     379        uint32_t first_block = ext4_block_group_get_inode_table_first_block(
     380                        bg_ref->block_group, sb);
     381
     382        uint32_t last_block = first_block + table_blocks - 1;
     383
     384        /* Initialization of all itable blocks */
     385        for (uint32_t fblock = first_block; fblock <= last_block; ++fblock) {
     386                block_t *block;
     387                rc = block_get(&block, bg_ref->fs->device, fblock, BLOCK_FLAGS_NOREAD);
     388                if (rc != EOK) {
     389                        return rc;
     390                }
     391
     392                memset(block->data, 0, block_size);
     393                block->dirty = true;
     394
     395                rc = block_put(block);
     396                if (rc != EOK) {
     397                        return rc;
     398                }
    203399        }
    204400
     
    249445
    250446        *ref = newref;
     447
     448        if (ext4_block_group_has_flag(newref->block_group,
     449                        EXT4_BLOCK_GROUP_BLOCK_UNINIT)) {
     450
     451                rc = ext4_filesystem_init_block_bitmap(newref);
     452                if (rc != EOK) {
     453                        block_put(newref->block);
     454                        free(newref);
     455                        return rc;
     456                }
     457                ext4_block_group_clear_flag(newref->block_group,
     458                                EXT4_BLOCK_GROUP_BLOCK_UNINIT);
     459
     460                newref->dirty = true;
     461        }
     462
     463        if (ext4_block_group_has_flag(newref->block_group,
     464                        EXT4_BLOCK_GROUP_INODE_UNINIT)) {
     465
     466                rc = ext4_filesystem_init_inode_bitmap(newref);
     467                if (rc != EOK) {
     468                        block_put(newref->block);
     469                        free(newref);
     470                        return rc;
     471                }
     472
     473                ext4_block_group_clear_flag(newref->block_group,
     474                                EXT4_BLOCK_GROUP_INODE_UNINIT);
     475
     476                ext4_block_group_set_itable_unused(newref->block_group,
     477                                newref->fs->superblock, 0);
     478
     479
     480                if (! ext4_block_group_has_flag(newref->block_group,
     481                                EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
     482
     483                        rc = ext4_filesystem_init_inode_table(newref);
     484                        if (rc != EOK) {
     485                                return rc;
     486                        }
     487
     488                        ext4_block_group_set_flag(newref->block_group,
     489                                        EXT4_BLOCK_GROUP_ITABLE_ZEROED);
     490
     491                }
     492                newref->dirty = true;
     493
     494        }
    251495
    252496        return EOK;
     
    11681412int ext4_filesystem_add_orphan(ext4_inode_ref_t *inode_ref)
    11691413{
    1170 
    1171         EXT4FS_DBG("adding orphan \%u", inode_ref->index);
    1172 
    11731414        uint32_t next_orphan = ext4_superblock_get_last_orphan(
    11741415                        inode_ref->fs->superblock);
     
    11921433int ext4_filesystem_delete_orphan(ext4_inode_ref_t *inode_ref)
    11931434{
    1194 
    1195         EXT4FS_DBG("adding orphan \%u", inode_ref->index);
    1196 
    11971435        int rc;
    11981436
  • uspace/lib/ext4/libext4_filesystem.h

    r865a4bf r4cdac68  
    4141extern int ext4_filesystem_check_sanity(ext4_filesystem_t *fs);
    4242extern int ext4_filesystem_check_features(ext4_filesystem_t *, bool *);
     43extern uint32_t ext4_filesystem_blockaddr2_index_in_group(ext4_superblock_t *,
     44                uint32_t);
     45extern uint32_t ext4_filesystem_index_in_group2blockaddr(ext4_superblock_t *,
     46                uint32_t, uint32_t);
    4347extern int ext4_filesystem_get_block_group_ref(ext4_filesystem_t *, uint32_t,
    4448    ext4_block_group_ref_t **);
  • uspace/lib/ext4/libext4_ialloc.c

    r865a4bf r4cdac68  
    141141                        sb, free_inodes);
    142142
    143         /* Set unused i-nodes count if supported */
    144         if (ext4_block_group_has_flag(bg_ref->block_group, EXT4_BLOCK_GROUP_INODE_UNINIT)) {
    145                 uint32_t unused_inodes = ext4_block_group_get_itable_unused(
    146                                 bg_ref->block_group, sb);
    147                 unused_inodes++;
    148                 ext4_block_group_set_itable_unused(bg_ref->block_group, sb, unused_inodes);
    149         }
    150 
    151143        bg_ref->dirty = true;
    152144
     
    241233                        ext4_block_group_set_free_inodes_count(bg, sb, free_inodes);
    242234
    243                         /* Decrement unused i-nodes counter if supported */
    244                         if (ext4_block_group_has_flag(bg, EXT4_BLOCK_GROUP_INODE_UNINIT)) {
    245                                 uint16_t unused_inodes = ext4_block_group_get_itable_unused(bg, sb);
    246                                 unused_inodes--;
    247                                 ext4_block_group_set_itable_unused(bg, sb, unused_inodes);
    248                         }
    249 
    250235                        /* Increment used directories counter */
    251236                        if (is_dir) {
Note: See TracChangeset for help on using the changeset viewer.