Changeset d241aae in mainline


Ignore:
Timestamp:
2011-02-15T19:24:38Z (14 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ce13577
Parents:
1d6f507
Message:

Add support for reading ext2 block group descriptors

Location:
uspace
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/ext2info/ext2info.c

    r1d6f507 rd241aae  
    5353
    5454static void syntax_print(void);
    55 static void print_superblock(ext2_superblock_t *sb);
     55static void print_superblock(ext2_superblock_t *);
     56static void print_block_groups(ext2_filesystem_t *);
     57static void print_block_group(ext2_block_group_t *);
    5658
    5759int main(int argc, char **argv)
     
    6264        devmap_handle_t handle;
    6365        ext2_filesystem_t filesystem;
     66        bool strict_check;
    6467       
    6568        if (argc < 2) {
     
    6871                return 1;
    6972        }
     73       
     74        strict_check = false;
     75        if (str_cmp(*argv, "--strict-check") == 0) {
     76                --argc; ++argv;
     77                strict_check = true;
     78        }
    7079
    7180        --argc; ++argv;
     
    94103        if (rc != EOK) {
    95104                printf(NAME ": Filesystem did not pass sanity check.\n");
    96                 return 3;
     105                if (strict_check) {
     106                        return 3;
     107                }
    97108        }
    98109       
    99110        print_superblock(filesystem.superblock);
     111        print_block_groups(&filesystem);
    100112
    101113        ext2_filesystem_fini(&filesystem);
     
    200212}
    201213
     214void print_block_groups(ext2_filesystem_t *filesystem) {
     215        uint32_t block_group_count;
     216        uint32_t i;
     217        ext2_block_group_ref_t *block_group_ref;
     218        int rc;
     219       
     220        printf("Block groups:\n");
     221       
     222        block_group_count = ext2_superblock_get_block_group_count(
     223            filesystem->superblock);
     224       
     225        for (i = 0; i < block_group_count; i++) {
     226                printf("  Block group %u\n", i);
     227                rc = ext2_filesystem_get_block_group_ref(filesystem, i, &block_group_ref);
     228                if (rc != EOK) {
     229                        printf("    Failed reading block group\n");
     230                        continue;
     231                }
     232               
     233                print_block_group(block_group_ref->block_group);
     234               
     235                rc = ext2_filesystem_put_block_group_ref(block_group_ref);
     236                if (rc != EOK) {
     237                        printf("    Failed freeing block group\n");
     238                }
     239        }
     240       
     241}
     242
     243void print_block_group(ext2_block_group_t *bg) {
     244        uint32_t block_bitmap_block;
     245        uint32_t inode_bitmap_block;
     246        uint32_t inode_table_first_block;
     247        uint16_t free_block_count;
     248        uint16_t free_inode_count;
     249        uint16_t directory_inode_count;
     250       
     251        block_bitmap_block = ext2_block_group_get_block_bitmap_block(bg);
     252        inode_bitmap_block = ext2_block_group_get_inode_bitmap_block(bg);
     253        inode_table_first_block = ext2_block_group_get_inode_table_first_block(bg);
     254        free_block_count = ext2_block_group_get_free_block_count(bg);
     255        free_inode_count = ext2_block_group_get_free_inode_count(bg);
     256        directory_inode_count = ext2_block_group_get_directory_inode_count(bg);
     257       
     258        printf("    Block bitmap block: %u\n", block_bitmap_block);
     259        printf("    Inode bitmap block: %u\n", inode_bitmap_block);
     260        printf("    Inode table's first block: %u\n", inode_table_first_block);
     261        printf("    Free blocks: %u\n", free_block_count);
     262        printf("    Free inodes: %u\n", free_inode_count);
     263        printf("    Directory inodes: %u\n", directory_inode_count);
     264}
     265
    202266/**
    203267 * @}
  • uspace/lib/ext2/Makefile

    r1d6f507 rd241aae  
    3636SOURCES = \
    3737        libext2_filesystem.c \
    38         libext2_superblock.c
     38        libext2_superblock.c \
     39        libext2_block_group.c
    3940
    4041include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/ext2/libext2.h

    r1d6f507 rd241aae  
    3838
    3939#include "libext2_superblock.h"
     40#include "libext2_block_group.h"
    4041#include "libext2_filesystem.h"
    4142
  • uspace/lib/ext2/libext2_filesystem.c

    r1d6f507 rd241aae  
    3434 */
    3535
    36 #include "libext2.h"
     36#include "libext2_filesystem.h"
     37#include "libext2_superblock.h"
     38#include "libext2_block_group.h"
    3739#include <errno.h>
    3840#include <libblock.h>
     
    105107
    106108/**
     109 * Get a reference to block descriptor
     110 *
     111 * @param fs Pointer to filesystem information
     112 * @param bgid Index of block group to find
     113 * @param ref Pointer where to store pointer to block group reference
     114 *
     115 * @return              EOK on success or negative error code on failure
     116 */
     117int ext2_filesystem_get_block_group_ref(ext2_filesystem_t *fs, uint32_t bgid,
     118    ext2_block_group_ref_t **ref)
     119{
     120        int rc;
     121        aoff64_t block_id;
     122        uint32_t descriptors_per_block;
     123        size_t offset;
     124        ext2_block_group_ref_t *newref;
     125       
     126        newref = malloc(sizeof(ext2_block_group_ref_t));
     127        if (newref == NULL) {
     128                return ENOMEM;
     129        }
     130       
     131        descriptors_per_block = ext2_superblock_get_block_size(fs->superblock)
     132            / EXT2_BLOCK_GROUP_DESCRIPTOR_SIZE;
     133       
     134        // Block group descriptor table starts at the next block after superblock
     135        block_id = ext2_superblock_get_first_block(fs->superblock) + 1;
     136       
     137        // Find the block containing the descriptor we are looking for
     138        block_id += bgid / descriptors_per_block;
     139        offset = (bgid % descriptors_per_block) * EXT2_BLOCK_GROUP_DESCRIPTOR_SIZE;
     140       
     141        rc = block_get(&newref->block, fs->device, block_id, 0);
     142        if (rc != EOK) {
     143                free(newref);
     144                return rc;
     145        }
     146       
     147        newref->block_group = newref->block->data + offset;
     148       
     149        *ref = newref;
     150       
     151        return EOK;
     152}
     153
     154/**
     155 * Free a reference to block group
     156 *
     157 * @param ref Pointer to block group reference to free
     158 *
     159 * @return              EOK on success or negative error code on failure
     160 */
     161int ext2_filesystem_put_block_group_ref(ext2_block_group_ref_t *ref)
     162{
     163        int rc;
     164       
     165        rc = block_put(ref->block);
     166        free(ref);
     167       
     168        return rc;
     169}
     170
     171/**
    107172 * Finalize an instance of filesystem
    108173 *
  • uspace/lib/ext2/libext2_filesystem.h

    r1d6f507 rd241aae  
    3939#include <libblock.h>
    4040#include "libext2_superblock.h"
     41#include "libext2_block_group.h"
    4142
    4243typedef struct ext2_filesystem {
     
    5253extern int ext2_filesystem_init(ext2_filesystem_t *, devmap_handle_t);
    5354extern int ext2_filesystem_check_sanity(ext2_filesystem_t *);
     55extern int ext2_filesystem_get_block_group_ref(ext2_filesystem_t *, uint32_t,
     56    ext2_block_group_ref_t **);
     57extern int ext2_filesystem_put_block_group_ref(ext2_block_group_ref_t *);
    5458extern void ext2_filesystem_fini(ext2_filesystem_t *);
    5559
  • uspace/lib/ext2/libext2_superblock.c

    r1d6f507 rd241aae  
    260260 * Compute count of block groups present in the filesystem
    261261 *
     262 * Note: This function works only for correct filesystem,
     263 *       i.e. it assumes that total block count > 0 and
     264 *       blocks per group > 0
     265 *
     266 * Example:
     267 *   If there are 3 blocks per group, the result should be as follows:
     268 *   Total blocks       Result
     269 *   1                          1
     270 *   2                          1
     271 *   3                          1
     272 *   4                          2
     273 *
     274 *
    262275 * @param sb pointer to superblock
    263276 */
    264277inline uint32_t ext2_superblock_get_block_group_count(ext2_superblock_t *sb)
    265278{
    266         return ext2_superblock_get_total_block_count(sb) /
    267             ext2_superblock_get_blocks_per_group(sb);
     279        /* We add one to the result because e.g. 2/3 = 0, while to store
     280         *  2 blocks in 3-block group we need one (1) block group
     281         *
     282         * We subtract one first because of special case that to store e.g.
     283         *  3 blocks in a 3-block group we need only one group
     284         *  (and 3/3 yields one - this is one more that we want as we
     285         *   already add one at the end)
     286         */
     287        return ((ext2_superblock_get_total_block_count(sb)-1) /
     288            ext2_superblock_get_blocks_per_group(sb))+1;
    268289}
    269290
Note: See TracChangeset for help on using the changeset viewer.