Changeset 1ac1ab4 in mainline for uspace/lib/ext4/libext4_filesystem.c


Ignore:
Timestamp:
2012-03-31T20:00:15Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a2fa350
Parents:
38384ae
Message:

simplied headers of more functions, improved bg_ref and inode_ref structures, added block group checksumming and fixed bug in block_group values updating

File:
1 edited

Legend:

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

    r38384ae r1ac1ab4  
    169169
    170170        newref->block_group = newref->block->data + offset;
     171        newref->fs = fs;
     172        newref->index = bgid;
    171173        newref->dirty = false;
    172174
     
    176178}
    177179
     180static uint16_t ext4_filesystem_bg_checksum(ext4_superblock_t *sb, uint32_t bgid,
     181                            ext4_block_group_t *bg)
     182{
     183        uint16_t crc = 0;
     184
     185        if (ext4_superblock_has_feature_read_only(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
     186
     187                void *base = bg;
     188                void *checksum = &bg->checksum;
     189
     190                uint32_t offset = (uint32_t)(checksum - base);
     191
     192                uint32_t le_group = host2uint32_t_le(bgid);
     193
     194                crc = crc16(~0, sb->uuid, sizeof(sb->uuid));
     195                crc = crc16(crc, (uint8_t *)&le_group, sizeof(le_group));
     196                crc = crc16(crc, (uint8_t *)bg, offset);
     197
     198                offset += sizeof(bg->checksum); /* skip checksum */
     199
     200                /* for checksum of struct ext4_group_desc do the rest...*/
     201                if ((ext4_superblock_has_feature_incompatible(sb, EXT4_FEATURE_INCOMPAT_64BIT)) &&
     202                        offset < ext4_superblock_get_desc_size(sb)) {
     203
     204                        crc = crc16(crc, ((uint8_t *)bg) + offset, ext4_superblock_get_desc_size(sb) - offset);
     205                }
     206        }
     207
     208        return crc;
     209
     210}
     211
     212
    178213int ext4_filesystem_put_block_group_ref(ext4_block_group_ref_t *ref)
    179214{
     
    181216
    182217        if (ref->dirty) {
     218                 uint16_t checksum = ext4_filesystem_bg_checksum(
     219                                ref->fs->superblock, ref->index, ref->block_group);
     220
     221                 ext4_block_group_set_checksum(ref->block_group, checksum);
     222
    183223                ref->block->dirty = true;
    184224        }
     
    242282         * in the reference
    243283         */
    244         newref->index = index+1;
     284        newref->index = index + 1;
     285        newref->fs = fs;
    245286        newref->dirty = false;
    246287
     
    321362}
    322363
    323 int ext4_filesystem_free_inode(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref)
     364int ext4_filesystem_free_inode(ext4_inode_ref_t *inode_ref)
    324365{
    325366        int rc;
     
    330371        uint32_t fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0);
    331372        if (fblock != 0) {
    332                 rc = ext4_balloc_free_block(fs, inode_ref, fblock);
     373                rc = ext4_balloc_free_block(inode_ref, fblock);
    333374                if (rc != EOK) {
    334375                        return rc;
     
    337378                ext4_inode_set_indirect_block(inode_ref->inode, 0, 0);
    338379        }
     380
     381        ext4_filesystem_t *fs = inode_ref->fs;
    339382
    340383        block_t *block;
     
    355398
    356399                        if (ind_block != 0) {
    357                                 rc = ext4_balloc_free_block(fs, inode_ref, ind_block);
     400                                rc = ext4_balloc_free_block(inode_ref, ind_block);
    358401                                if (rc != EOK) {
    359402                                        block_put(block);
     
    364407
    365408                block_put(block);
    366                 rc = ext4_balloc_free_block(fs, inode_ref, fblock);
     409                rc = ext4_balloc_free_block(inode_ref, fblock);
    367410                if (rc != EOK) {
    368411                        return rc;
     
    398441
    399442                                        if (ind_subblock != 0) {
    400                                                 rc = ext4_balloc_free_block(fs, inode_ref, ind_subblock);
     443                                                rc = ext4_balloc_free_block(inode_ref, ind_subblock);
    401444                                                if (rc != EOK) {
    402445                                                        block_put(subblock);
     
    411454                        }
    412455
    413                         rc = ext4_balloc_free_block(fs, inode_ref, ind_block);
     456                        rc = ext4_balloc_free_block(inode_ref, ind_block);
    414457                        if (rc != EOK) {
    415458                                block_put(block);
     
    421464
    422465                block_put(block);
    423                 rc = ext4_balloc_free_block(fs, inode_ref, fblock);
     466                rc = ext4_balloc_free_block(inode_ref, fblock);
    424467                if (rc != EOK) {
    425468                        return rc;
     
    445488}
    446489
    447 int ext4_filesystem_truncate_inode(ext4_filesystem_t *fs,
     490int ext4_filesystem_truncate_inode(
    448491                ext4_inode_ref_t *inode_ref, aoff64_t new_size)
    449492{
    450493        int rc;
    451494
    452         if (! ext4_inode_can_truncate(fs->superblock, inode_ref->inode)) {
     495        ext4_superblock_t *sb = inode_ref->fs->superblock;
     496
     497        if (! ext4_inode_can_truncate(sb, inode_ref->inode)) {
    453498                // Unable to truncate
    454499                return EINVAL;
    455500        }
    456501
    457         aoff64_t old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
     502        aoff64_t old_size = ext4_inode_get_size(sb, inode_ref->inode);
    458503        if (old_size == new_size) {
    459504                // Nothing to do
     
    467512
    468513        aoff64_t size_diff = old_size - new_size;
    469         uint32_t block_size  = ext4_superblock_get_block_size(fs->superblock);
     514        uint32_t block_size  = ext4_superblock_get_block_size(sb);
    470515        uint32_t diff_blocks_count = size_diff / block_size;
    471516        if (size_diff % block_size != 0) {
     
    480525        // starting from 1 because of logical blocks are numbered from 0
    481526        for (uint32_t i = 1; i <= diff_blocks_count; ++i) {
    482                 rc = ext4_filesystem_release_inode_block(fs, inode_ref, old_blocks_count - i);
     527                rc = ext4_filesystem_release_inode_block(inode_ref, old_blocks_count - i);
    483528                if (rc != EOK) {
    484529                        return rc;
     
    493538}
    494539
    495 int ext4_filesystem_get_inode_data_block_index(ext4_filesystem_t *fs,
    496                 ext4_inode_ref_t *inode_ref, aoff64_t iblock, uint32_t* fblock)
    497 {
    498         int rc;
    499 
     540int ext4_filesystem_get_inode_data_block_index(ext4_inode_ref_t *inode_ref,
     541                aoff64_t iblock, uint32_t* fblock)
     542{
     543        int rc;
     544
     545        ext4_filesystem_t *fs = inode_ref->fs;
    500546
    501547        uint32_t current_block;
     
    504550        if (ext4_superblock_has_feature_incompatible(fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    505551                        ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
    506                 rc = ext4_extent_find_block(fs, inode_ref, iblock, &current_block);
     552                rc = ext4_extent_find_block(inode_ref, iblock, &current_block);
    507553
    508554                if (rc != EOK) {
     
    591637
    592638
    593 int ext4_filesystem_set_inode_data_block_index(ext4_filesystem_t *fs,
    594                 ext4_inode_ref_t *inode_ref, aoff64_t iblock, uint32_t fblock)
    595 {
    596         int rc;
    597 
     639int ext4_filesystem_set_inode_data_block_index(ext4_inode_ref_t *inode_ref,
     640                aoff64_t iblock, uint32_t fblock)
     641{
     642        int rc;
     643
     644        ext4_filesystem_t *fs = inode_ref->fs;
    598645
    599646        /* Handle inode using extents */
     
    635682
    636683        if (current_block == 0) {
    637                 rc = ext4_balloc_alloc_block(fs, inode_ref, &new_block_addr);
     684                rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
    638685                if (rc != EOK) {
    639686                        return rc;
     
    646693                rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD);
    647694                if (rc != EOK) {
    648                         ext4_balloc_free_block(fs, inode_ref, new_block_addr);
     695                        ext4_balloc_free_block(inode_ref, new_block_addr);
    649696                        return rc;
    650697                }
     
    674721
    675722                if ((level > 1) && (current_block == 0)) {
    676                         rc = ext4_balloc_alloc_block(fs, inode_ref, &new_block_addr);
     723                        rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
    677724                        if (rc != EOK) {
    678725                                block_put(block);
     
    727774}
    728775
    729 int ext4_filesystem_release_inode_block(ext4_filesystem_t *fs,
     776int ext4_filesystem_release_inode_block(
    730777                ext4_inode_ref_t *inode_ref, uint32_t iblock)
    731778{
     
    733780
    734781        uint32_t fblock;
     782
     783        ext4_filesystem_t *fs = inode_ref->fs;
    735784
    736785        /* TODO Handle extents */
     
    772821
    773822                ext4_inode_set_direct_block(inode, iblock, 0);
    774                 return ext4_balloc_free_block(fs, inode_ref, fblock);
     823                return ext4_balloc_free_block(inode_ref, fblock);
    775824        }
    776825
     
    837886        }
    838887
    839         return ext4_balloc_free_block(fs, inode_ref, fblock);
    840 
    841 }
    842 
    843 int ext4_filesystem_add_orphan(ext4_filesystem_t *fs,
    844                 ext4_inode_ref_t *inode_ref)
    845 {
    846         uint32_t next_orphan = ext4_superblock_get_last_orphan(fs->superblock);
     888        return ext4_balloc_free_block(inode_ref, fblock);
     889
     890}
     891
     892int ext4_filesystem_add_orphan(ext4_inode_ref_t *inode_ref)
     893{
     894        uint32_t next_orphan = ext4_superblock_get_last_orphan(
     895                        inode_ref->fs->superblock);
    847896        ext4_inode_set_deletion_time(inode_ref->inode, next_orphan);
    848         ext4_superblock_set_last_orphan(fs->superblock, inode_ref->index);
     897        ext4_superblock_set_last_orphan(
     898                        inode_ref->fs->superblock, inode_ref->index);
    849899        inode_ref->dirty = true;
    850900
     
    852902}
    853903
    854 int ext4_filesystem_delete_orphan(ext4_filesystem_t *fs,
    855                 ext4_inode_ref_t *inode_ref)
    856 {
    857         int rc;
    858 
    859         uint32_t last_orphan = ext4_superblock_get_last_orphan(fs->superblock);
     904int ext4_filesystem_delete_orphan(ext4_inode_ref_t *inode_ref)
     905{
     906        int rc;
     907
     908        uint32_t last_orphan = ext4_superblock_get_last_orphan(
     909                        inode_ref->fs->superblock);
    860910        assert(last_orphan > 0);
    861911
     
    863913
    864914        if (last_orphan == inode_ref->index) {
    865                 ext4_superblock_set_last_orphan(fs->superblock, next_orphan);
     915                ext4_superblock_set_last_orphan(inode_ref->fs->superblock, next_orphan);
    866916                ext4_inode_set_deletion_time(inode_ref->inode, 0);
    867917                inode_ref->dirty = true;
     
    870920
    871921        ext4_inode_ref_t *current;
    872         rc = ext4_filesystem_get_inode_ref(fs, last_orphan, &current);
     922        rc = ext4_filesystem_get_inode_ref(inode_ref->fs, last_orphan, &current);
    873923        if (rc != EOK) {
    874924                return rc;
     
    889939                ext4_filesystem_put_inode_ref(current);
    890940
    891                 rc = ext4_filesystem_get_inode_ref(fs, next_orphan, &current);
     941                rc = ext4_filesystem_get_inode_ref(inode_ref->fs, next_orphan, &current);
    892942                if (rc != EOK) {
    893943                        return rc;
Note: See TracChangeset for help on using the changeset viewer.