Changeset 6accc5cf in mainline


Ignore:
Timestamp:
2015-07-28T14:12:56Z (9 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b10460a
Parents:
47726b5e (diff), fb4d788 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge ext4fs improvements

Location:
uspace
Files:
1 added
2 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/crypto/Makefile

    r47726b5e r6accc5cf  
    3333        crypto.c \
    3434        aes.c \
    35         rc4.c
     35        rc4.c \
     36        crc16_ibm.c
    3637
    3738include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/crypto/crypto.h

    r47726b5e r6accc5cf  
    5656extern int pbkdf2(uint8_t *, size_t, uint8_t *, size_t, uint8_t *);
    5757
     58extern uint16_t crc16_ibm(uint16_t crc, uint8_t *buf, size_t len);
     59
    5860#endif
  • uspace/lib/ext4/Makefile

    r47726b5e r6accc5cf  
    2929USPACE_PREFIX = ../..
    3030LIBRARY = libext4
    31 EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX)
    32 LIBS = $(LIBBLOCK_PREFIX)/libblock.a
     31EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBCRYPTO_PREFIX)
     32LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBCRYPTO_PREFIX)/libcrypto.a
    3333
    3434SOURCES = \
     
    3636        libext4_bitmap.c \
    3737        libext4_block_group.c \
    38         libext4_crc.c \
    3938        libext4_directory.c \
    4039        libext4_directory_index.c \
  • uspace/lib/ext4/libext4.h

    r47726b5e r6accc5cf  
    3737#include "libext4_bitmap.h"
    3838#include "libext4_block_group.h"
    39 #include "libext4_crc.h"
    4039#include "libext4_directory.h"
    4140#include "libext4_directory_index.h"
  • uspace/lib/ext4/libext4_balloc.c

    r47726b5e r6accc5cf  
    3939#include "libext4.h"
    4040
    41 /** Compute number of block group from block address.
    42  *
    43  * @param sb         Superblock pointer.
    44  * @param block_addr Absolute address of block.
    45  *
    46  * @return Block group index
    47  *
    48  */
    49 static uint32_t ext4_balloc_get_bgid_of_block(ext4_superblock_t *sb,
    50     uint32_t block_addr)
    51 {
    52         uint32_t blocks_per_group =
    53             ext4_superblock_get_blocks_per_group(sb);
    54         uint32_t first_block =
    55             ext4_superblock_get_first_data_block(sb);
    56        
    57         /* First block == 0 or 1 */
    58         if (first_block == 0)
    59                 return block_addr / blocks_per_group;
    60         else
    61                 return (block_addr - 1) / blocks_per_group;
    62 }
    63 
    6441/** Free block.
    6542 *
     
    7653       
    7754        /* Compute indexes */
    78         uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, block_addr);
     55        uint32_t block_group = ext4_filesystem_blockaddr2group(sb, block_addr);
    7956        uint32_t index_in_group =
    8057            ext4_filesystem_blockaddr2_index_in_group(sb, block_addr);
     
    135112}
    136113
    137 /** Free continuous set of blocks.
    138  *
    139  * @param inode_ref Inode, where the blocks are allocated
    140  * @param first     First block to release
    141  * @param count     Number of blocks to release
    142  *
    143  */
    144 int ext4_balloc_free_blocks(ext4_inode_ref_t *inode_ref,
     114static int ext4_balloc_free_blocks_internal(ext4_inode_ref_t *inode_ref,
    145115    uint32_t first, uint32_t count)
    146116{
    147117        ext4_filesystem_t *fs = inode_ref->fs;
    148118        ext4_superblock_t *sb = fs->superblock;
    149        
     119
    150120        /* Compute indexes */
    151         uint32_t block_group_first =
    152             ext4_balloc_get_bgid_of_block(sb, first);
    153         uint32_t block_group_last =
    154             ext4_balloc_get_bgid_of_block(sb, first + count - 1);
    155        
     121        uint32_t block_group_first = ext4_filesystem_blockaddr2group(sb,
     122            first);
     123        uint32_t block_group_last = ext4_filesystem_blockaddr2group(sb,
     124            first + count - 1);
     125
    156126        assert(block_group_first == block_group_last);
    157        
     127
    158128        /* Load block group reference */
    159129        ext4_block_group_ref_t *bg_ref;
     
    161131        if (rc != EOK)
    162132                return rc;
    163        
     133
    164134        uint32_t index_in_group_first =
    165135            ext4_filesystem_blockaddr2_index_in_group(sb, first);
    166        
     136
    167137        /* Load block with bitmap */
    168138        uint32_t bitmap_block_addr =
    169139            ext4_block_group_get_block_bitmap(bg_ref->block_group, sb);
    170        
     140
    171141        block_t *bitmap_block;
    172142        rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
     
    175145                return rc;
    176146        }
    177        
     147
    178148        /* Modify bitmap */
    179149        ext4_bitmap_free_bits(bitmap_block->data, index_in_group_first, count);
    180150        bitmap_block->dirty = true;
    181        
     151
    182152        /* Release block with bitmap */
    183153        rc = block_put(bitmap_block);
     
    187157                return rc;
    188158        }
    189        
     159
    190160        uint32_t block_size = ext4_superblock_get_block_size(sb);
    191        
     161
    192162        /* Update superblock free blocks count */
    193163        uint32_t sb_free_blocks =
     
    195165        sb_free_blocks += count;
    196166        ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
    197        
     167
    198168        /* Update inode blocks count */
    199169        uint64_t ino_blocks =
     
    202172        ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
    203173        inode_ref->dirty = true;
    204        
     174
    205175        /* Update block group free blocks count */
    206176        uint32_t free_blocks =
     
    210180            sb, free_blocks);
    211181        bg_ref->dirty = true;
    212        
     182
    213183        /* Release block group reference */
    214184        return ext4_filesystem_put_block_group_ref(bg_ref);
    215185}
    216186
     187/** Free continuous set of blocks.
     188 *
     189 * @param inode_ref Inode, where the blocks are allocated
     190 * @param first     First block to release
     191 * @param count     Number of blocks to release
     192 *
     193 */
     194int ext4_balloc_free_blocks(ext4_inode_ref_t *inode_ref,
     195    uint32_t first, uint32_t count)
     196{
     197        int r;
     198        uint32_t gid;
     199        uint64_t limit;
     200        ext4_filesystem_t *fs = inode_ref->fs;
     201        ext4_superblock_t *sb = fs->superblock;
     202
     203        while (count) {
     204                gid = ext4_filesystem_blockaddr2group(sb, first);
     205                limit = ext4_filesystem_index_in_group2blockaddr(sb, 0,
     206                    gid + 1);
     207
     208                if ((first + count) >= limit) {
     209                        /* This extent spans over 2 or more block groups,
     210                         * we'll break it into smaller parts.
     211                         */
     212                        uint32_t s = limit - first;
     213
     214                        r = ext4_balloc_free_blocks_internal(inode_ref,
     215                            first, s);
     216                        if (r != EOK)
     217                                return r;
     218
     219                        first = limit;
     220                        count -= s;
     221                } else {
     222                        return ext4_balloc_free_blocks_internal(inode_ref,
     223                            first, count);
     224                }
     225        }
     226
     227        return EOK;
     228}
     229
    217230/** Compute first block for data in block group.
    218231 *
     
    227240    ext4_block_group_ref_t *bg_ref)
    228241{
    229         uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
    230         uint32_t inode_table_first_block =
    231             ext4_block_group_get_inode_table_first_block(bg_ref->block_group, sb);
    232         uint16_t inode_table_item_size = ext4_superblock_get_inode_size(sb);
    233         uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
    234         uint32_t block_size = ext4_superblock_get_block_size(sb);
    235         uint32_t inode_table_bytes;
    236        
    237         if (bg_ref->index < block_group_count - 1) {
    238                 inode_table_bytes = inodes_per_group * inode_table_item_size;
    239         } else {
    240                 /* Last block group could be smaller */
    241                 uint32_t inodes_count_total = ext4_superblock_get_inodes_count(sb);
    242                 inode_table_bytes =
    243                     (inodes_count_total - ((block_group_count - 1) * inodes_per_group)) *
    244                     inode_table_item_size;
    245         }
    246        
    247         uint32_t inode_table_blocks = inode_table_bytes / block_size;
    248        
    249         if (inode_table_bytes % block_size)
    250                 inode_table_blocks++;
    251        
    252         return inode_table_first_block + inode_table_blocks;
     242        uint32_t r;
     243        uint64_t itable = ext4_block_group_get_inode_table_first_block(
     244            bg_ref->block_group, sb);
     245        uint32_t itable_sz = ext4_filesystem_bg_get_itable_size(sb, bg_ref);
     246
     247        if (!ext4_superblock_has_feature_incompatible(sb,
     248            EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
     249                /* If we are not using FLEX_BG, the first data block
     250                 * is always after the inode table.
     251                 */
     252                r = itable + itable_sz;
     253                return ext4_filesystem_blockaddr2_index_in_group(sb, r);
     254        }
     255
     256        uint64_t bbmap = ext4_block_group_get_block_bitmap(bg_ref->block_group,
     257            sb);
     258        uint64_t ibmap = ext4_block_group_get_inode_bitmap(bg_ref->block_group,
     259            sb);
     260
     261        r = ext4_filesystem_index_in_group2blockaddr(sb, 0, bg_ref->index);
     262        r += ext4_filesystem_bg_get_backup_blocks(bg_ref);
     263
     264        if (ext4_filesystem_blockaddr2group(sb, bbmap) != bg_ref->index)
     265                bbmap = -1; /* Invalid */
     266
     267        if (ext4_filesystem_blockaddr2group(sb, ibmap) != bg_ref->index)
     268                ibmap = -1;
     269
     270        while (1) {
     271                if (r == bbmap || r == ibmap)
     272                        r++;
     273                else if (r >= itable && r < (itable + itable_sz))
     274                        r = itable + itable_sz;
     275                else
     276                        break;
     277        }
     278
     279        return r;
    253280}
    254281
     
    264291        *goal = 0;
    265292        ext4_superblock_t *sb = inode_ref->fs->superblock;
    266        
     293
    267294        uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
    268295        uint32_t block_size = ext4_superblock_get_block_size(sb);
    269296        uint32_t inode_block_count = inode_size / block_size;
    270        
     297
    271298        if (inode_size % block_size != 0)
    272299                inode_block_count++;
    273        
     300
    274301        /* If inode has some blocks, get last block address + 1 */
    275302        if (inode_block_count > 0) {
     
    278305                if (rc != EOK)
    279306                        return rc;
    280                
     307
    281308                if (goal != 0) {
    282309                        (*goal)++;
    283310                        return EOK;
    284311                }
    285                
    286312                /* If goal == 0, sparse file -> continue */
    287313        }
    288        
     314
    289315        /* Identify block group of inode */
    290316        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
    291317        uint32_t block_group = (inode_ref->index - 1) / inodes_per_group;
    292         block_size = ext4_superblock_get_block_size(sb);
    293        
     318
    294319        /* Load block group reference */
    295320        ext4_block_group_ref_t *bg_ref;
     
    298323        if (rc != EOK)
    299324                return rc;
    300        
    301         /* Compute indexes */
    302         uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
    303         uint32_t inode_table_first_block =
    304             ext4_block_group_get_inode_table_first_block(bg_ref->block_group, sb);
    305         uint16_t inode_table_item_size = ext4_superblock_get_inode_size(sb);
    306         uint32_t inode_table_bytes;
    307        
    308         /* Check for last block group */
    309         if (block_group < block_group_count - 1) {
    310                 inode_table_bytes = inodes_per_group * inode_table_item_size;
    311         } else {
    312                 /* Last block group could be smaller */
    313                 uint32_t inodes_count_total = ext4_superblock_get_inodes_count(sb);
    314                 inode_table_bytes =
    315                     (inodes_count_total - ((block_group_count - 1) * inodes_per_group)) *
    316                     inode_table_item_size;
    317         }
    318        
    319         uint32_t inode_table_blocks = inode_table_bytes / block_size;
    320        
    321         if (inode_table_bytes % block_size)
    322                 inode_table_blocks++;
    323        
    324         *goal = inode_table_first_block + inode_table_blocks;
    325        
     325
     326        *goal = ext4_balloc_get_first_data_block_in_group(sb, bg_ref);
     327
    326328        return ext4_filesystem_put_block_group_ref(bg_ref);
    327329}
     
    353355       
    354356        /* Load block group number for goal and relative index */
    355         uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, goal);
     357        uint32_t block_group = ext4_filesystem_blockaddr2group(sb, goal);
    356358        uint32_t index_in_group =
    357359            ext4_filesystem_blockaddr2_index_in_group(sb, goal);
     
    626628       
    627629        /* Compute indexes */
    628         uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, fblock);
     630        uint32_t block_group = ext4_filesystem_blockaddr2group(sb, fblock);
    629631        uint32_t index_in_group =
    630632            ext4_filesystem_blockaddr2_index_in_group(sb, fblock);
  • uspace/lib/ext4/libext4_filesystem.c

    r47726b5e r6accc5cf  
    4040#include <malloc.h>
    4141#include <ipc/vfs.h>
     42#include <align.h>
     43#include <crypto.h>
    4244#include "libext4.h"
    4345
     
    5355    enum cache_mode cmode)
    5456{
     57        int rc;
    5558        ext4_superblock_t *temp_superblock = NULL;
    5659
     
    5861
    5962        /* Initialize block library (4096 is size of communication channel) */
    60         int rc = block_init(EXCHANGE_SERIALIZE, fs->device, 4096);
     63        rc = block_init(EXCHANGE_SERIALIZE, fs->device, 4096);
    6164        if (rc != EOK)
    6265                goto err;
     
    139142        /* Release memory space for superblock */
    140143        free(fs->superblock);
    141        
     144
    142145        /* Finish work with block library */
    143146        block_cache_fini(fs->device);
     
    250253}
    251254
     255/** Convert the absolute block number to group number
     256 *
     257 * @param sb    Pointer to the superblock
     258 * @param b     Absolute block number
     259 *
     260 * @return      Group number
     261 */
     262uint32_t ext4_filesystem_blockaddr2group(ext4_superblock_t *sb, uint64_t b)
     263{
     264        uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
     265        uint32_t first_block = ext4_superblock_get_first_data_block(sb);
     266
     267        return (b - first_block) / blocks_per_group;
     268}
     269
    252270/** Initialize block bitmap in block group.
    253271 *
     
    259277static int ext4_filesystem_init_block_bitmap(ext4_block_group_ref_t *bg_ref)
    260278{
     279        uint64_t itb;
     280        uint32_t sz;
     281        uint32_t i;
     282
    261283        /* Load bitmap */
    262         uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
     284        ext4_superblock_t *sb = bg_ref->fs->superblock;
     285        uint64_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
     286            bg_ref->block_group, bg_ref->fs->superblock);
     287        uint64_t bitmap_inode_addr = ext4_block_group_get_inode_bitmap(
    263288            bg_ref->block_group, bg_ref->fs->superblock);
    264289       
     
    272297       
    273298        /* Initialize all bitmap bits to zero */
    274         uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock);
     299        uint32_t block_size = ext4_superblock_get_block_size(sb);
    275300        memset(bitmap, 0, block_size);
    276301       
    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        
     302        /* Determine the number of reserved blocks in the group */
     303        uint32_t reserved_cnt = ext4_filesystem_bg_get_backup_blocks(bg_ref);
     304
    285305        /* Set bits from to first block to first data block - 1 to one (allocated) */
    286         for (uint32_t block = first_idx; block < first_data_idx; ++block)
     306        for (uint32_t block = 0; block < reserved_cnt; ++block)
    287307                ext4_bitmap_set_bit(bitmap, block);
    288        
     308
     309        uint32_t bitmap_block_gid = ext4_filesystem_blockaddr2group(sb,
     310            bitmap_block_addr);
     311        if (bitmap_block_gid == bg_ref->index) {
     312                ext4_bitmap_set_bit(bitmap,
     313                    ext4_filesystem_blockaddr2_index_in_group(sb, bitmap_block_addr));
     314        }
     315
     316        uint32_t bitmap_inode_gid = ext4_filesystem_blockaddr2group(sb,
     317            bitmap_inode_addr);
     318        if (bitmap_inode_gid == bg_ref->index) {
     319                ext4_bitmap_set_bit(bitmap,
     320                    ext4_filesystem_blockaddr2_index_in_group(sb, bitmap_inode_addr));
     321        }
     322
     323        itb = ext4_block_group_get_inode_table_first_block(bg_ref->block_group,
     324            sb);
     325        sz = ext4_filesystem_bg_get_itable_size(sb, bg_ref);
     326
     327        for (i = 0; i < sz; ++i, ++itb) {
     328                uint32_t gid = ext4_filesystem_blockaddr2group(sb, itb);
     329                if (gid == bg_ref->index) {
     330                        ext4_bitmap_set_bit(bitmap,
     331                            ext4_filesystem_blockaddr2_index_in_group(sb, itb));
     332                }
     333        }
     334
    289335        bitmap_block->dirty = true;
    290336       
     
    423469        }
    424470       
    425         /* Inititialize in-memory representation */
     471        /* Initialize in-memory representation */
    426472        newref->block_group = newref->block->data + offset;
    427473        newref->fs = fs;
     
    488534        /* If checksum not supported, 0 will be returned */
    489535        uint16_t crc = 0;
    490        
     536
    491537        /* Compute the checksum only if the filesystem supports it */
    492538        if (ext4_superblock_has_feature_read_only(sb,
     
    501547               
    502548                /* Initialization */
    503                 crc = crc16(~0, sb->uuid, sizeof(sb->uuid));
     549                crc = crc16_ibm(~0, sb->uuid, sizeof(sb->uuid));
    504550               
    505551                /* Include index of block group */
    506                 crc = crc16(crc, (uint8_t *) &le_group, sizeof(le_group));
     552                crc = crc16_ibm(crc, (uint8_t *) &le_group, sizeof(le_group));
    507553               
    508554                /* Compute crc from the first part (stop before checksum field) */
    509                 crc = crc16(crc, (uint8_t *) bg, offset);
     555                crc = crc16_ibm(crc, (uint8_t *) bg, offset);
    510556               
    511557                /* Skip checksum */
     
    516562                    EXT4_FEATURE_INCOMPAT_64BIT)) &&
    517563                    (offset < ext4_superblock_get_desc_size(sb)))
    518                         crc = crc16(crc, ((uint8_t *) bg) + offset,
     564                        crc = crc16_ibm(crc, ((uint8_t *) bg) + offset,
    519565                            ext4_superblock_get_desc_size(sb) - offset);
    520566        }
     
    523569}
    524570
     571/** Get the size of the block group's inode table
     572 *
     573 * @param sb     Pointer to the superblock
     574 * @param bg_ref Pointer to the block group reference
     575 *
     576 * @return       Size of the inode table in blocks.
     577 */
     578uint32_t ext4_filesystem_bg_get_itable_size(ext4_superblock_t *sb,
     579    ext4_block_group_ref_t *bg_ref)
     580{
     581        uint32_t itable_size;
     582        uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
     583        uint16_t inode_table_item_size = ext4_superblock_get_inode_size(sb);
     584        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
     585        uint32_t block_size = ext4_superblock_get_block_size(sb);
     586
     587        if (bg_ref->index < block_group_count - 1) {
     588                itable_size = inodes_per_group * inode_table_item_size;
     589        } else {
     590                /* Last block group could be smaller */
     591                uint32_t inodes_count_total = ext4_superblock_get_inodes_count(sb);
     592                itable_size =
     593                    (inodes_count_total - ((block_group_count - 1) * inodes_per_group)) *
     594                    inode_table_item_size;
     595        }
     596
     597        return ROUND_UP(itable_size, block_size) / block_size;
     598}
     599
     600/* Check if n is a power of p */
     601static bool is_power_of(uint32_t n, unsigned p)
     602{
     603        if (p == 1 && n != p)
     604                return false;
     605
     606        while (n != p) {
     607                if (n < p)
     608                        return false;
     609                else if ((n % p) != 0)
     610                        return false;
     611
     612                n /= p;
     613        }
     614
     615        return true;
     616}
     617
     618/** Get the number of blocks used by superblock + gdt + reserved gdt backups
     619 *
     620 * @param bg    Pointer to block group
     621 *
     622 * @return      Number of blocks
     623 */
     624uint32_t ext4_filesystem_bg_get_backup_blocks(ext4_block_group_ref_t *bg)
     625{
     626        uint32_t const idx = bg->index;
     627        uint32_t r = 0;
     628        bool has_backups = false;
     629        ext4_superblock_t *sb = bg->fs->superblock;
     630
     631        /* First step: determine if the block group contains the backups */
     632
     633        if (idx <= 1)
     634                has_backups = true;
     635        else {
     636                if (ext4_superblock_has_feature_compatible(sb,
     637                    EXT4_FEATURE_COMPAT_SPARSE_SUPER2)) {
     638                        uint32_t g1, g2;
     639
     640                        ext4_superblock_get_backup_groups_sparse2(sb,
     641                            &g1, &g2);
     642
     643                        if (idx == g1 || idx == g2)
     644                                has_backups = true;
     645                } else if (!ext4_superblock_has_feature_read_only(sb,
     646                    EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
     647                        /* Very old fs were all block groups have
     648                         * superblock and block descriptors backups.
     649                         */
     650                        has_backups = true;
     651                } else {
     652                        if ((idx & 1) && (is_power_of(idx, 3) ||
     653                            is_power_of(idx, 5) || is_power_of(idx, 7)))
     654                                has_backups = true;
     655                }
     656        }
     657
     658        if (has_backups) {
     659                uint32_t bg_count;
     660                uint32_t bg_desc_sz;
     661                uint32_t gdt_table; /* Size of the GDT in blocks */
     662                uint32_t block_size = ext4_superblock_get_block_size(sb);
     663
     664                /* Now we know that this block group has backups,
     665                 * we have to compute how many blocks are reserved
     666                 * for them
     667                 */
     668
     669                if (idx == 0 && block_size == 1024) {
     670                        /* Special case for first group were the boot block
     671                         * resides
     672                         */
     673                        r++;
     674                }
     675
     676                /* This accounts for the superblock */
     677                r++;
     678
     679                /* Add the number of blocks used for the GDT */
     680                bg_count = ext4_superblock_get_block_group_count(sb);
     681                bg_desc_sz = ext4_superblock_get_desc_size(sb);
     682                gdt_table = ROUND_UP(bg_count * bg_desc_sz, block_size) /
     683                    block_size;
     684
     685                r += gdt_table;
     686
     687                /* And now the number of reserved GDT blocks */
     688                r += ext4_superblock_get_reserved_gdt_blocks(sb);
     689        }
     690
     691        return r;
     692}
     693
    525694/** Put reference to block group.
    526695 *
    527  * @oaram ref Pointer for reference to be put back
     696 * @param ref Pointer for reference to be put back
    528697 *
    529698 * @return Error code
  • uspace/lib/ext4/libext4_filesystem.h

    r47726b5e r6accc5cf  
    4747extern uint32_t ext4_filesystem_index_in_group2blockaddr(ext4_superblock_t *,
    4848    uint32_t, uint32_t);
     49extern uint32_t ext4_filesystem_blockaddr2group(ext4_superblock_t *, uint64_t);
    4950extern int ext4_filesystem_get_block_group_ref(ext4_filesystem_t *, uint32_t,
    5051    ext4_block_group_ref_t **);
     
    6465extern int ext4_filesystem_append_inode_block(ext4_inode_ref_t *, uint32_t *,
    6566    uint32_t *);
     67uint32_t ext4_filesystem_bg_get_backup_blocks(ext4_block_group_ref_t *bg);
     68uint32_t ext4_filesystem_bg_get_itable_size(ext4_superblock_t *sb,
     69    ext4_block_group_ref_t *bg_ref);
    6670
    6771#endif
  • uspace/lib/ext4/libext4_superblock.c

    r47726b5e r6accc5cf  
    12981298}
    12991299
     1300/** Get the backup groups used with SPARSE_SUPER2
     1301 *
     1302 * @param sb    Pointer to the superblock
     1303 * @param g1    Output pointer to the first backup group
     1304 * @param g2    Output pointer to the second backup group
     1305 */
     1306void ext4_superblock_get_backup_groups_sparse2(ext4_superblock_t *sb,
     1307    uint32_t *g1, uint32_t *g2)
     1308{
     1309        *g1 = uint32_t_le2host(sb->backup_bgs[0]);
     1310        *g2 = uint32_t_le2host(sb->backup_bgs[1]);
     1311}
     1312
     1313/** Set the backup groups (SPARSE SUPER2)
     1314 *
     1315 * @param sb    Pointer to the superblock
     1316 * @param g1    Index of the first group
     1317 * @param g2    Index of the second group
     1318 */
     1319void ext4_superblock_set_backup_groups_sparse2(ext4_superblock_t *sb,
     1320    uint32_t g1, uint32_t g2)
     1321{
     1322        sb->backup_bgs[0] = host2uint32_t_le(g1);
     1323        sb->backup_bgs[1] = host2uint32_t_le(g2);
     1324}
     1325
     1326/** Get the number of blocks (per group) reserved to GDT expansion
     1327 *
     1328 * @param sb    Pointer to the superblock
     1329 *
     1330 * @return      Number of blocks
     1331 */
     1332uint32_t ext4_superblock_get_reserved_gdt_blocks(ext4_superblock_t *sb)
     1333{
     1334        return uint32_t_le2host(sb->reserved_gdt_blocks);
     1335}
     1336
     1337/** Set the number of blocks (per group) reserved to GDT expansion
     1338 *
     1339 * @param sb    Pointer to the superblock
     1340 * @param n     Number of reserved blocks
     1341 */
     1342void ext4_superblock_set_reserved_gdt_blocks(ext4_superblock_t *sb,
     1343    uint32_t n)
     1344{
     1345        sb->reserved_gdt_blocks = host2uint32_t_le(n);
     1346}
     1347
    13001348/**
    13011349 * @}
  • uspace/lib/ext4/libext4_superblock.h

    r47726b5e r6accc5cf  
    135135extern void ext4_superblock_set_flags(ext4_superblock_t *, uint32_t);
    136136
     137extern void ext4_superblock_get_backup_groups_sparse2(ext4_superblock_t *sb,
     138    uint32_t *g1, uint32_t *g2);
     139extern void ext4_superblock_set_backup_groups_sparse2(ext4_superblock_t *sb,
     140    uint32_t g1, uint32_t g2);
     141
     142extern uint32_t ext4_superblock_get_reserved_gdt_blocks(ext4_superblock_t *sb);
     143extern void ext4_superblock_set_reserved_gdt_blocks(ext4_superblock_t *sb,
     144    uint32_t n);
     145
    137146/* More complex superblock functions */
    138147extern bool ext4_superblock_has_flag(ext4_superblock_t *, uint32_t);
  • uspace/lib/ext4/libext4_types.h

    r47726b5e r6accc5cf  
    8383         * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
    8484         */
    85         uint8_t s_prealloc_blocks;       /* Number of blocks to try to preallocate */
    86         uint8_t s_prealloc_dir_blocks;   /* Number to preallocate for dirs */
    87         uint16_t s_reserved_gdt_blocks;  /* Per group desc for online growth */
     85        uint8_t prealloc_blocks;        /* Number of blocks to try to preallocate */
     86        uint8_t prealloc_dir_blocks;    /* Number to preallocate for dirs */
     87        uint16_t reserved_gdt_blocks;   /* Per group desc for online growth */
    8888       
    8989        /*
     
    133133        uint64_t last_error_block;          /* Block involved of last error */
    134134        uint8_t last_error_func[32];        /* Function where the error happened */
    135         uint8_t mount_opts[64];
    136         uint32_t padding[112];              /* Padding to the end of the block */
     135        uint8_t mount_opts[64];             /* String containing the mount options */
     136        uint32_t usr_quota_inum;            /* Inode number of user quota file */
     137        uint32_t grp_quota_inum;            /* Inode number of group quota file */
     138        uint32_t overhead_blocks;           /* Overhead blocks/clusters */
     139        uint32_t backup_bgs[2];             /* Block groups containing superblock backups (if SPARSE_SUPER2) */
     140        uint32_t encrypt_algos;             /* Encrypt algorithm in use */
     141        uint32_t padding[105];              /* Padding to the end of the block */
    137142} __attribute__((packed)) ext4_superblock_t;
    138143
     
    176181#define EXT4_FEATURE_COMPAT_RESIZE_INODE   0x0010
    177182#define EXT4_FEATURE_COMPAT_DIR_INDEX      0x0020
     183#define EXT4_FEATURE_COMPAT_SPARSE_SUPER2  0x0200
    178184
    179185/*
     
    208214        (EXT4_FEATURE_INCOMPAT_FILETYPE | \
    209215        EXT4_FEATURE_INCOMPAT_EXTENTS | \
    210         EXT4_FEATURE_INCOMPAT_64BIT)
     216        EXT4_FEATURE_INCOMPAT_64BIT | \
     217        EXT4_FEATURE_INCOMPAT_FLEX_BG)
    211218
    212219#define EXT4_FEATURE_RO_COMPAT_SUPP \
  • uspace/srv/fs/ext4fs/Makefile

    r47726b5e r6accc5cf  
    2828
    2929USPACE_PREFIX = ../../..
    30 LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBFS_PREFIX)/libfs.a $(LIBEXT4_PREFIX)/libext4.a
    31 EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX) -I$(LIBEXT4_PREFIX)
     30LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBFS_PREFIX)/libfs.a \
     31    $(LIBEXT4_PREFIX)/libext4.a $(LIBCRYPTO_PREFIX)/libcrypto.a
     32EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX) -I$(LIBEXT4_PREFIX) -I$(LIBCRYPTO_PREFIX)
    3233BINARY = ext4fs
    3334STATIC_NEEDED = y
Note: See TracChangeset for help on using the changeset viewer.