Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 3c8b0a8 in mainline


Ignore:
Timestamp:
2018-12-15T15:48:59Z (3 years ago)
Author:
GitHub <noreply@…>
Branches:
lfn, master
Children:
4bb4cf88
Parents:
b6d5e31 (diff), 6ea5e7a (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.
git-author:
Maurizio Lombardi <m.lombardi85@…> (2018-12-15 15:48:59)
git-committer:
GitHub <noreply@…> (2018-12-15 15:48:59)
Message:

Merge pull request #143 from maurizio-lombardi/ext4_fixes_v2

Ext4 fixes

Location:
uspace
Files:
7 edited

Legend:

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

    rb6d5e31 r3c8b0a8  
    5656        aoff64_t nblocks;
    5757        const char *label = "";
     58        unsigned int bsize = 1024;
    5859
    5960        cfg.version = ext4_def_fs_version;
     
    7980
    8081                        nblocks = strtol(*argv, &endptr, 10);
     82                        if (*endptr != '\0') {
     83                                printf(NAME ": Error, invalid argument.\n");
     84                                syntax_print();
     85                                return 1;
     86                        }
     87
     88                        --argc;
     89                        ++argv;
     90                        continue;
     91                }
     92
     93                if (str_cmp(*argv, "--bsize") == 0) {
     94                        --argc;
     95                        ++argv;
     96                        if (*argv == NULL) {
     97                                printf(NAME ": Error, argument missing.\n");
     98                                syntax_print();
     99                                return 1;
     100                        }
     101
     102                        bsize = strtol(*argv, &endptr, 10);
    81103                        if (*endptr != '\0') {
    82104                                printf(NAME ": Error, invalid argument.\n");
     
    159181
    160182        cfg.volume_name = label;
     183        cfg.bsize = bsize;
    161184        (void) nblocks;
    162185
     
    178201            "\t--size <sectors> Filesystem size, overrides device size\n"
    179202            "\t--label <label>  Volume label\n"
    180             "\t--type <fstype>  Filesystem type (ext2, ext2old)\n");
     203            "\t--type <fstype>  Filesystem type (ext2, ext2old)\n"
     204            "\t--bsize <bytes>  Filesystem block size in bytes (default = 1024)\n");
    181205}
    182206
  • uspace/lib/ext4/include/ext4/cfg.h

    rb6d5e31 r3c8b0a8  
    5353        /** Volume name encoded as UTF-8 string */
    5454        const char *volume_name;
     55        /** Filesystem block size */
     56        size_t bsize;
    5557} ext4_cfg_t;
    5658
  • uspace/lib/ext4/include/ext4/superblock.h

    rb6d5e31 r3c8b0a8  
    147147extern void ext4_superblock_set_reserved_gdt_blocks(ext4_superblock_t *sb,
    148148    uint32_t n);
     149extern uint32_t ext4_superblock_get_flex_group_size(ext4_superblock_t *sb);
    149150
    150151/* More complex superblock functions */
  • uspace/lib/ext4/src/balloc.c

    rb6d5e31 r3c8b0a8  
    261261                 * is always after the inode table.
    262262                 */
     263                return itable + itable_sz;
     264        }
     265
     266        uint32_t flex_group_size = ext4_superblock_get_flex_group_size(sb);
     267        if ((bg_ref->index % flex_group_size) == 0) {
     268                /* This is the base group */
     269                uint32_t i;
     270
    263271                r = itable + itable_sz;
    264                 return ext4_filesystem_blockaddr2_index_in_group(sb, r);
    265         }
    266 
    267         uint64_t bbmap = ext4_block_group_get_block_bitmap(bg_ref->block_group,
    268             sb);
    269         uint64_t ibmap = ext4_block_group_get_inode_bitmap(bg_ref->block_group,
    270             sb);
    271 
    272         r = ext4_filesystem_index_in_group2blockaddr(sb, 0, bg_ref->index);
    273         r += ext4_filesystem_bg_get_backup_blocks(bg_ref);
    274 
    275         if (ext4_filesystem_blockaddr2group(sb, bbmap) != bg_ref->index)
    276                 bbmap = -1; /* Invalid */
    277 
    278         if (ext4_filesystem_blockaddr2group(sb, ibmap) != bg_ref->index)
    279                 ibmap = -1;
    280 
    281         while (true) {
    282                 if (r == bbmap || r == ibmap)
    283                         r++;
    284                 else if (r >= itable && r < (itable + itable_sz))
    285                         r = itable + itable_sz;
    286                 else
    287                         break;
    288         }
    289 
    290         return r;
     272
     273                uint32_t total_groups = ext4_superblock_get_block_group_count(sb);
     274                for (i = bg_ref->index + 1;
     275                    i < min(total_groups, bg_ref->index + flex_group_size); ++i) {
     276                        r += ext4_filesystem_bg_get_itable_size(sb, i);
     277                }
     278
     279                return r;
     280        }
     281
     282        uint64_t base_addr = ext4_filesystem_index_in_group2blockaddr(sb, 0,
     283            bg_ref->index);
     284        uint32_t reserved = ext4_filesystem_bg_get_backup_blocks(bg_ref);
     285
     286        return base_addr + reserved;
    291287}
    292288
  • uspace/lib/ext4/src/filesystem.c

    rb6d5e31 r3c8b0a8  
    714714                /* One for block bitmap one for inode bitmap */
    715715                free_blocks = free_blocks - reserved - 2 - inode_table_blocks;
    716                 if (bg_index == 0)
    717                         ++free_blocks; /* XXX Why? */
    718716
    719717                ext4_block_group_set_free_blocks_count(bg_ref->block_group,
  • uspace/lib/ext4/src/ialloc.c

    rb6d5e31 r3c8b0a8  
    176176errno_t ext4_ialloc_alloc_inode(ext4_filesystem_t *fs, uint32_t *index, bool is_dir)
    177177{
     178        int pick_first_free = 0;
    178179        ext4_superblock_t *sb = fs->superblock;
    179 
    180         uint32_t bgid = 0;
    181         uint32_t bg_count = ext4_superblock_get_block_group_count(sb);
    182         uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
    183         uint32_t avg_free_inodes = sb_free_inodes / bg_count;
     180        uint32_t bgid;
     181        uint32_t sb_free_inodes;
     182        uint32_t avg_free_inodes;
     183        uint32_t const bg_count = ext4_superblock_get_block_group_count(sb);
     184
     185retry:
     186
     187        bgid = 0;
     188        sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
     189        avg_free_inodes = sb_free_inodes / bg_count;
    184190
    185191        /* Try to find free i-node in all block groups */
     
    210216                 * blocks.
    211217                 */
    212                 if (((free_inodes >= avg_free_inodes) || (bgid == bg_count - 1)) &&
    213                     (free_blocks > 0)) {
     218                if (((free_inodes >= avg_free_inodes) ||
     219                    (bgid == bg_count - 1) || pick_first_free) && (free_blocks > 0)) {
    214220                        /* Load block with bitmap */
    215221                        uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
     
    307313        }
    308314
     315        /* Try again with less strict conditions */
     316        if (pick_first_free == 0) {
     317                pick_first_free = 1;
     318                goto retry;
     319        }
     320
    309321        return ENOSPC;
    310322}
  • uspace/lib/ext4/src/superblock.c

    rb6d5e31 r3c8b0a8  
    13151315            ext4_superblock_get_blocks_per_group(sb);
    13161316        uint64_t total_blocks =
    1317             ext4_superblock_get_blocks_count(sb) - 1;
     1317            ext4_superblock_get_blocks_count(sb);
     1318        uint32_t first_block =
     1319            ext4_superblock_get_first_data_block(sb);
    13181320
    13191321        if (bgid < block_group_count - 1)
    13201322                return blocks_per_group;
    13211323        else
    1322                 return (total_blocks - ((block_group_count - 1) * blocks_per_group));
     1324                return (total_blocks - ((block_group_count - 1) * blocks_per_group)) - first_block;
    13231325}
    13241326
     
    13921394{
    13931395        sb->reserved_gdt_blocks = host2uint32_t_le(n);
     1396}
     1397
     1398/** Get the size of the flex groups
     1399 *
     1400 * @param sb    Pointer to the superblock
     1401 *
     1402 * @return      Size of the flex groups
     1403 */
     1404uint32_t ext4_superblock_get_flex_group_size(ext4_superblock_t *sb)
     1405{
     1406        return 2 << sb->log_groups_per_flex;
    13941407}
    13951408
     
    14651478                 */
    14661479
    1467                 if (idx == 0 && block_size == 1024) {
    1468                         /*
    1469                          * Special case for first group were the boot block
    1470                          * resides
    1471                          */
    1472                         r++;
    1473                 }
    1474 
    14751480                /* This accounts for the superblock */
    14761481                r++;
     
    15051510        uuid_t uuid;
    15061511        uint32_t cur_ts;
    1507         uint64_t first_block;
     1512        uint64_t first_block = 0;
    15081513        uint64_t fs_blocks;
    15091514        uint32_t blocks_count;
     
    15181523        uint32_t idx;
    15191524        size_t fs_bsize;
     1525        size_t fs_bsize_log;
    15201526        errno_t rc;
    15211527        struct timespec ts;
     
    15331539        cur_ts = ts.tv_sec;
    15341540
    1535         fs_bsize = 1024;
    1536         first_block = 1; /* 1 for 1k block size, 0 otherwise */
     1541        fs_bsize = cfg->bsize;
     1542        switch (fs_bsize) {
     1543        case 1024:
     1544                first_block = 1;
     1545                fs_bsize_log = 0;
     1546                blocks_group = 8192;
     1547                break;
     1548        case 2048:
     1549                fs_bsize_log = 1;
     1550                blocks_group = 8192 * 2;
     1551                break;
     1552        case 4096:
     1553                fs_bsize_log = 2;
     1554                blocks_group = 8192 * 4;
     1555                break;
     1556        default:
     1557                return ENOTSUP;
     1558        }
    15371559
    15381560        if (fs_bsize % dev_bsize == 0) {
     
    15431565                fs_blocks = dev_bcnt * (dev_bsize / fs_bsize);
    15441566        }
    1545 
    1546         /* FS blocks per group */
    1547         blocks_group = 8 * fs_bsize;
    15481567
    15491568        /* Inodes per group */
     
    15811600        ext4_superblock_set_free_inodes_count(sb, inodes_count);
    15821601        ext4_superblock_set_first_data_block(sb, first_block);
    1583         /* Block size will be 1024 bytes */
    1584         ext4_superblock_set_log_block_size(sb, 0);
     1602        ext4_superblock_set_log_block_size(sb, fs_bsize_log);
    15851603        /* Fragment size should be equal to block size */
    1586         ext4_superblock_set_log_frag_size(sb, 0);
     1604        ext4_superblock_set_log_frag_size(sb, fs_bsize_log);
    15871605        ext4_superblock_set_blocks_per_group(sb, blocks_group);
    15881606        /* Should be the same as blocks per group. */
     
    16341652        /* Compute free blocks */
    16351653        free_blocks = blocks_count;
    1636         ++free_blocks; // XXX Why?
    16371654        for (idx = 0; idx < ngroups; idx++) {
    16381655                free_blocks -= ext4_superblock_get_group_backup_blocks(sb, idx);
Note: See TracChangeset for help on using the changeset viewer.