Changeset 304faab in mainline for uspace/lib/ext4/libext4_ialloc.c


Ignore:
Timestamp:
2012-01-24T09:24:14Z (13 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
786bd56
Parents:
08cc26b
Message:

Very simple allocation algorithm

File:
1 edited

Legend:

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

    r08cc26b r304faab  
    5656
    5757
    58 int ext4_ialloc_free_inode(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref)
     58int ext4_ialloc_free_inode(ext4_filesystem_t *fs, uint32_t index, bool is_dir)
    5959{
    6060        int rc;
    6161
    62         uint32_t block_group = ext4_ialloc_get_bgid_of_inode(
    63                         fs->superblock, inode_ref->index);
     62        ext4_superblock_t *sb = fs->superblock;
     63
     64        uint32_t block_group = ext4_ialloc_get_bgid_of_inode(sb, index);
    6465
    6566        ext4_block_group_ref_t *bg_ref;
    6667        rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
    6768        if (rc != EOK) {
    68                 EXT4FS_DBG("error in loading bg_ref \%d", rc);
    6969                return rc;
    7070        }
    7171
    7272        uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
    73                         bg_ref->block_group, fs->superblock);
     73                        bg_ref->block_group, sb);
    7474        block_t *bitmap_block;
    75         rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
    76         if (rc != EOK) {
    77                 EXT4FS_DBG("error in loading bitmap \%d", rc);
    78                 return rc;
    79         }
    80 
    81         uint32_t index_in_group = ext4_ialloc_inode2index_in_group(
    82                                 fs->superblock, inode_ref->index);
     75        rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, BLOCK_FLAGS_NONE);
     76        if (rc != EOK) {
     77                return rc;
     78        }
     79
     80        uint32_t index_in_group = ext4_ialloc_inode2index_in_group(sb, index);
    8381        ext4_bitmap_free_bit(bitmap_block->data, index_in_group);
    8482        bitmap_block->dirty = true;
     
    8886                // Error in saving bitmap
    8987                ext4_filesystem_put_block_group_ref(bg_ref);
    90                 EXT4FS_DBG("error in saving bitmap \%d", rc);
    91                 return rc;
    92         }
    93 
    94         // if inode is directory, decrement directories count
    95         if (ext4_inode_is_type(fs->superblock, inode_ref->inode, EXT4_INODE_MODE_DIRECTORY)) {
     88                return rc;
     89        }
     90
     91        // if inode is directory, decrement used directories count
     92        if (is_dir) {
    9693                uint32_t bg_used_dirs = ext4_block_group_get_used_dirs_count(
    97                         bg_ref->block_group, fs->superblock);
     94                        bg_ref->block_group, sb);
    9895                bg_used_dirs--;
    9996                ext4_block_group_set_used_dirs_count(
    100                                 bg_ref->block_group, fs->superblock, bg_used_dirs);
    101         }
    102 
    103         // Update superblock free inodes count
    104         uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(fs->superblock);
    105         sb_free_inodes++;
    106         ext4_superblock_set_free_inodes_count(fs->superblock, sb_free_inodes);
     97                                bg_ref->block_group, sb, bg_used_dirs);
     98        }
    10799
    108100        // Update block group free inodes count
    109101        uint32_t free_inodes = ext4_block_group_get_free_inodes_count(
    110                         bg_ref->block_group, fs->superblock);
     102                        bg_ref->block_group, sb);
    111103        free_inodes++;
    112104        ext4_block_group_set_free_inodes_count(bg_ref->block_group,
    113                         fs->superblock, free_inodes);
     105                        sb, free_inodes);
    114106        bg_ref->dirty = true;
    115107
    116108        rc = ext4_filesystem_put_block_group_ref(bg_ref);
    117109        if (rc != EOK) {
    118                 EXT4FS_DBG("error in saving bg_ref \%d", rc);
    119                 // TODO error
    120                 return rc;
    121         }
     110                return rc;
     111        }
     112
     113        // Update superblock free inodes count
     114        uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
     115        sb_free_inodes++;
     116        ext4_superblock_set_free_inodes_count(sb, sb_free_inodes);
    122117
    123118        return EOK;
    124119}
    125120
     121int ext4_ialloc_alloc_inode(ext4_filesystem_t *fs, uint32_t *index, bool is_dir)
     122{
     123        int rc;
     124
     125        ext4_superblock_t *sb = fs->superblock;
     126
     127        uint32_t bgid = 0;
     128        uint32_t bg_count = ext4_superblock_get_block_group_count(sb);
     129
     130        while (bgid < bg_count) {
     131
     132                ext4_block_group_ref_t *bg_ref;
     133                rc = ext4_filesystem_get_block_group_ref(fs, bgid, &bg_ref);
     134                if (rc != EOK) {
     135                        return rc;
     136                }
     137                ext4_block_group_t *bg = bg_ref->block_group;
     138
     139                uint32_t free_blocks = ext4_block_group_get_free_blocks_count(bg, sb);
     140                uint32_t free_inodes = ext4_block_group_get_free_inodes_count(bg, sb);
     141                uint32_t used_dirs = ext4_block_group_get_used_dirs_count(bg, sb);
     142
     143                if ((free_inodes > 0) && (free_blocks > 0)) {
     144
     145                        uint32_t bitmap_block_addr =  ext4_block_group_get_block_bitmap(
     146                                        bg_ref->block_group, sb);
     147
     148                        block_t *bitmap_block;
     149                        rc = block_get(&bitmap_block, fs->device,
     150                                        bitmap_block_addr, BLOCK_FLAGS_NONE);
     151                        if (rc != EOK) {
     152                                return rc;
     153                        }
     154
     155                        // Alloc bit
     156                        uint32_t inodes_in_group = ext4_superblock_get_inodes_in_group(sb, bgid);
     157                        rc = ext4_bitmap_find_free_bit_and_set(bitmap_block->data, 0, index, inodes_in_group);
     158                        if (rc == ENOSPC) {
     159                                block_put(bitmap_block);
     160                                ext4_filesystem_put_block_group_ref(bg_ref);
     161                                continue;
     162                        }
     163
     164                        bitmap_block->dirty = true;
     165
     166                        rc = block_put(bitmap_block);
     167                        if (rc != EOK) {
     168                                return rc;
     169                        }
     170
     171                        // Modify filesystem counters
     172                        free_inodes--;
     173                        ext4_block_group_set_free_inodes_count(bg, sb, free_inodes);
     174
     175                        if (is_dir) {
     176                                used_dirs--;
     177                                ext4_block_group_set_used_dirs_count(bg, sb, used_dirs);
     178                        }
     179
     180                        bg_ref->dirty = true;
     181
     182                        rc = ext4_filesystem_put_block_group_ref(bg_ref);
     183                        if (rc != EOK) {
     184                                // TODO
     185                        }
     186
     187                        uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
     188                        sb_free_inodes--;
     189                        ext4_superblock_set_free_inodes_count(sb, sb_free_inodes);
     190
     191                        return EOK;
     192
     193                } else {
     194                        // Not modified
     195                        ext4_filesystem_put_block_group_ref(bg_ref);
     196                }
     197
     198        }
     199
     200        return ENOSPC;
     201}
    126202
    127203/**
Note: See TracChangeset for help on using the changeset viewer.