Ignore:
File:
1 edited

Legend:

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

    rc1fd281 reb94d84  
    4040#include <malloc.h>
    4141#include <ipc/vfs.h>
    42 #include <align.h>
    4342#include "libext4.h"
    4443
     
    251250}
    252251
    253 /** Convert the absolute block number to group number
    254  *
    255  * @param sb    Pointer to the superblock
    256  * @param b     Absolute block number
    257  *
    258  * @return      Group number
    259  */
    260 uint32_t ext4_filesystem_blockaddr2group(ext4_superblock_t *sb, uint64_t b)
    261 {
    262         uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
    263         uint32_t first_block = ext4_superblock_get_first_data_block(sb);
    264 
    265         return (b - first_block) / blocks_per_group;
    266 }
    267 
    268252/** Initialize block bitmap in block group.
    269253 *
     
    275259static int ext4_filesystem_init_block_bitmap(ext4_block_group_ref_t *bg_ref)
    276260{
    277         uint64_t itb;
    278         uint32_t sz;
    279         uint32_t i;
    280 
    281261        /* Load bitmap */
    282         ext4_superblock_t *sb = bg_ref->fs->superblock;
    283         uint64_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
    284             bg_ref->block_group, bg_ref->fs->superblock);
    285         uint64_t bitmap_inode_addr = ext4_block_group_get_inode_bitmap(
     262        uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
    286263            bg_ref->block_group, bg_ref->fs->superblock);
    287264       
     
    295272       
    296273        /* Initialize all bitmap bits to zero */
    297         uint32_t block_size = ext4_superblock_get_block_size(sb);
     274        uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock);
    298275        memset(bitmap, 0, block_size);
    299276       
    300         /* Determine the number of reserved blocks in the group */
    301         uint32_t reserved_cnt = ext4_filesystem_bg_get_backup_blocks(bg_ref);
    302 
     277        /* Determine first block and first data block in group */
     278        uint32_t first_idx = 0;
     279       
     280        uint32_t first_data = ext4_balloc_get_first_data_block_in_group(
     281            bg_ref->fs->superblock, bg_ref);
     282        uint32_t first_data_idx = ext4_filesystem_blockaddr2_index_in_group(
     283            bg_ref->fs->superblock, first_data);
     284       
    303285        /* Set bits from to first block to first data block - 1 to one (allocated) */
    304         for (uint32_t block = 0; block < reserved_cnt; ++block)
     286        for (uint32_t block = first_idx; block < first_data_idx; ++block)
    305287                ext4_bitmap_set_bit(bitmap, block);
    306 
    307         uint32_t bitmap_block_gid = ext4_filesystem_blockaddr2group(sb,
    308             bitmap_block_addr);
    309         if (bitmap_block_gid == bg_ref->index) {
    310                 ext4_bitmap_set_bit(bitmap,
    311                     ext4_filesystem_blockaddr2_index_in_group(sb, bitmap_block_addr));
    312         }
    313 
    314         uint32_t bitmap_inode_gid = ext4_filesystem_blockaddr2group(sb,
    315             bitmap_inode_addr);
    316         if (bitmap_inode_gid == bg_ref->index) {
    317                 ext4_bitmap_set_bit(bitmap,
    318                     ext4_filesystem_blockaddr2_index_in_group(sb, bitmap_inode_addr));
    319         }
    320 
    321         itb = ext4_block_group_get_inode_table_first_block(bg_ref->block_group,
    322             sb);
    323         sz = ext4_filesystem_bg_get_itable_size(sb, bg_ref);
    324 
    325         for (i = 0; i < sz; ++i, ++itb) {
    326                 uint32_t gid = ext4_filesystem_blockaddr2group(sb, itb);
    327                 if (gid == bg_ref->index) {
    328                         ext4_bitmap_set_bit(bitmap,
    329                             ext4_filesystem_blockaddr2_index_in_group(sb, itb));
    330                 }
    331         }
    332 
     288       
    333289        bitmap_block->dirty = true;
    334290       
     
    467423        }
    468424       
    469         /* Initialize in-memory representation */
     425        /* Inititialize in-memory representation */
    470426        newref->block_group = newref->block->data + offset;
    471427        newref->fs = fs;
     
    567523}
    568524
    569 /** Get the size of the block group's inode table
    570  *
    571  * @param sb     Pointer to the superblock
    572  * @param bg_ref Pointer to the block group reference
    573  *
    574  * @return       Size of the inode table in blocks.
    575  */
    576 uint32_t ext4_filesystem_bg_get_itable_size(ext4_superblock_t *sb,
    577     ext4_block_group_ref_t *bg_ref)
    578 {
    579         uint32_t itable_size;
    580         uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
    581         uint16_t inode_table_item_size = ext4_superblock_get_inode_size(sb);
    582         uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
    583         uint32_t block_size = ext4_superblock_get_block_size(sb);
    584 
    585         if (bg_ref->index < block_group_count - 1) {
    586                 itable_size = inodes_per_group * inode_table_item_size;
    587         } else {
    588                 /* Last block group could be smaller */
    589                 uint32_t inodes_count_total = ext4_superblock_get_inodes_count(sb);
    590                 itable_size =
    591                     (inodes_count_total - ((block_group_count - 1) * inodes_per_group)) *
    592                     inode_table_item_size;
    593         }
    594 
    595         return ROUND_UP(itable_size, block_size) / block_size;
    596 }
    597 
    598 /* Check if n is a power of p */
    599 static bool is_power_of(uint32_t n, unsigned p)
    600 {
    601         if (p == 1 && n != p)
    602                 return false;
    603 
    604         while (n != p) {
    605                 if (n < p)
    606                         return false;
    607                 else if ((n % p) != 0)
    608                         return false;
    609 
    610                 n /= p;
    611         }
    612 
    613         return true;
    614 }
    615 
    616 /** Get the number of blocks used by superblock + gdt + reserved gdt backups
    617  *
    618  * @param bg    Pointer to block group
    619  *
    620  * @return      Number of blocks
    621  */
    622 uint32_t ext4_filesystem_bg_get_backup_blocks(ext4_block_group_ref_t *bg)
    623 {
    624         uint32_t const idx = bg->index;
    625         uint32_t r = 0;
    626         bool has_backups = false;
    627         ext4_superblock_t *sb = bg->fs->superblock;
    628 
    629         /* First step: determine if the block group contains the backups */
    630 
    631         if (idx <= 1)
    632                 has_backups = true;
    633         else {
    634                 if (ext4_superblock_has_feature_compatible(sb,
    635                     EXT4_FEATURE_COMPAT_SPARSE_SUPER2)) {
    636                         uint32_t g1, g2;
    637 
    638                         ext4_superblock_get_backup_groups_sparse2(sb,
    639                             &g1, &g2);
    640 
    641                         if (idx == g1 || idx == g2)
    642                                 has_backups = true;
    643                 } else if (!ext4_superblock_has_feature_read_only(sb,
    644                     EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
    645                         /* Very old fs were all block groups have
    646                          * superblock and block descriptors backups.
    647                          */
    648                         has_backups = true;
    649                 } else {
    650                         if ((idx & 1) && (is_power_of(idx, 3) ||
    651                             is_power_of(idx, 5) || is_power_of(idx, 7)))
    652                                 has_backups = true;
    653                 }
    654         }
    655 
    656         if (has_backups) {
    657                 uint32_t bg_count;
    658                 uint32_t bg_desc_sz;
    659                 uint32_t gdt_table; /* Size of the GDT in blocks */
    660                 uint32_t block_size = ext4_superblock_get_block_size(sb);
    661 
    662                 /* Now we know that this block group has backups,
    663                  * we have to compute how many blocks are reserved
    664                  * for them
    665                  */
    666 
    667                 if (idx == 0 && block_size == 1024) {
    668                         /* Special case for first group were the boot block
    669                          * resides
    670                          */
    671                         r++;
    672                 }
    673 
    674                 /* This accounts for the superblock */
    675                 r++;
    676 
    677                 /* Add the number of blocks used for the GDT */
    678                 bg_count = ext4_superblock_get_block_group_count(sb);
    679                 bg_desc_sz = ext4_superblock_get_desc_size(sb);
    680                 gdt_table = ROUND_UP(bg_count * bg_desc_sz, block_size) /
    681                     block_size;
    682 
    683                 r += gdt_table;
    684 
    685                 /* And now the number of reserved GDT blocks */
    686                 r += ext4_superblock_get_reserved_gdt_blocks(sb);
    687         }
    688 
    689         return r;
    690 }
    691 
    692525/** Put reference to block group.
    693526 *
    694  * @param ref Pointer for reference to be put back
     527 * @oaram ref Pointer for reference to be put back
    695528 *
    696529 * @return Error code
Note: See TracChangeset for help on using the changeset viewer.