Changeset 447201e in mainline


Ignore:
Timestamp:
2015-04-16T19:34:06Z (10 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7f29575
Parents:
6dd7f65
Message:

libext4: adds a function that, given a block group ref, calculates the number of blocks reserved to GDT+superblock backups.

Location:
uspace/lib/ext4
Files:
2 edited

Legend:

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

    r6dd7f65 r447201e  
    4040#include <malloc.h>
    4141#include <ipc/vfs.h>
     42#include <align.h>
    4243#include "libext4.h"
    4344
     
    521522       
    522523        return crc;
     524}
     525
     526/* Check if n is a power of p */
     527static bool is_power_of(uint32_t n, unsigned p)
     528{
     529        if (p == 1 && n != p)
     530                return false;
     531
     532        while (n != p) {
     533                if (n < p)
     534                        return false;
     535                else if ((n % p) != 0)
     536                        return false;
     537
     538                n /= p;
     539        }
     540
     541        return true;
     542}
     543
     544/** Get the number of blocks used by superblock + gdt + reserved gdt backups
     545 *
     546 * @param bg    Pointer to block group
     547 *
     548 * @return      Number of blocks
     549 */
     550uint32_t ext4_block_group_get_backup_blocks(ext4_block_group_ref_t *bg)
     551{
     552        uint32_t const idx = bg->index;
     553        uint32_t r = 0;
     554        bool has_backups = false;
     555        ext4_superblock_t *sb = bg->fs->superblock;
     556
     557        /* First step: determine if the block group contains the backups */
     558
     559        if (idx <= 1)
     560                has_backups = true;
     561        else {
     562                if (ext4_superblock_has_feature_compatible(sb,
     563                    EXT4_FEATURE_COMPAT_SPARSE_SUPER2)) {
     564                        uint32_t g1, g2;
     565
     566                        ext4_superblock_get_backup_groups_sparse2(sb,
     567                            &g1, &g2);
     568
     569                        if (idx == g1 || idx == g2)
     570                                has_backups = true;
     571                } else if (!ext4_superblock_has_feature_read_only(sb,
     572                    EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
     573                        /* Very old fs were all block groups have
     574                         * superblock and block descriptors backups.
     575                         */
     576                        has_backups = true;
     577                } else {
     578                        if ((idx & 1) && (is_power_of(idx, 3) ||
     579                            is_power_of(idx, 5) || is_power_of(idx, 7)))
     580                                has_backups = true;
     581                }
     582        }
     583
     584        if (has_backups) {
     585                uint32_t bg_count;
     586                uint32_t bg_desc_sz;
     587                uint32_t gdt_table; /* Size of the GDT in blocks */
     588                uint32_t block_size = ext4_superblock_get_block_size(sb);
     589
     590                /* Now we know that this block group has backups,
     591                 * we have to compute how many blocks are reserved
     592                 * for them
     593                 */
     594
     595                if (idx == 0 && block_size == 1024) {
     596                        /* Special case for first group were the boot block
     597                         * resides
     598                         */
     599                        r++;
     600                }
     601
     602                /* This accounts for the superblock */
     603                r++;
     604
     605                /* Add the number of blocks used for the GDT */
     606                bg_count = ext4_superblock_get_block_group_count(sb);
     607                bg_desc_sz = ext4_superblock_get_desc_size(sb);
     608                gdt_table = ROUND_UP(bg_count * bg_desc_sz, block_size) /
     609                    block_size;
     610
     611                r += gdt_table;
     612
     613                /* And now the number of reserved GDT blocks */
     614                r += ext4_superblock_get_reserved_gdt_blocks(sb);
     615        }
     616
     617        return r;
    523618}
    524619
  • uspace/lib/ext4/libext4_filesystem.h

    r6dd7f65 r447201e  
    6464extern int ext4_filesystem_append_inode_block(ext4_inode_ref_t *, uint32_t *,
    6565    uint32_t *);
     66uint32_t ext4_block_group_get_backup_blocks(ext4_block_group_ref_t *bg);
    6667
    6768#endif
Note: See TracChangeset for help on using the changeset viewer.