Changeset 304faab in mainline


Ignore:
Timestamp:
2012-01-24T09:24:14Z (12 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

Location:
uspace
Files:
5 edited

Legend:

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

    r08cc26b r304faab  
    266266}
    267267
    268 int ext4_filesystem_alloc_inode(ext4_filesystem_t *fs, ext4_inode_ref_t **inode_ref)
    269 {
    270         // TODO
    271         return EOK;
    272 }
    273 
    274 int ext4_filesystem_init_inode(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref, int flags)
    275 {
    276         ext4_inode_t *inode = inode_ref->inode;
    277 
     268int ext4_filesystem_alloc_inode(ext4_filesystem_t *fs,
     269                ext4_inode_ref_t **inode_ref, int flags)
     270{
     271        int rc;
     272
     273        bool is_dir = false;
    278274        if (flags & L_DIRECTORY) {
     275                is_dir = true;
     276        }
     277
     278        // allocate inode
     279        uint32_t index;
     280        rc = ext4_ialloc_alloc_inode(fs, &index, is_dir);
     281        if (rc != EOK) {
     282                return rc;
     283        }
     284
     285        // TODO extents, dir_index etc...
     286        rc = ext4_filesystem_get_inode_ref(fs, index, inode_ref);
     287        if (rc != EOK) {
     288                ext4_ialloc_free_inode(fs, index, is_dir);
     289                return rc;
     290        }
     291
     292        // init inode
     293        ext4_inode_t *inode = (*inode_ref)->inode;
     294
     295        if (is_dir) {
    279296                ext4_inode_set_mode(fs->superblock, inode, EXT4_INODE_MODE_DIRECTORY);
    280297                ext4_inode_set_links_count(inode, 1); // '.' entry
     
    299316        }
    300317
     318        (*inode_ref)->dirty = true;
     319
    301320        return EOK;
    302321}
     
    408427
    409428        // Free inode
    410         rc = ext4_ialloc_free_inode(fs, inode_ref);
     429        if (ext4_inode_is_type(fs->superblock, inode_ref->inode,
     430                        EXT4_INODE_MODE_DIRECTORY)) {
     431                rc = ext4_ialloc_free_inode(fs, inode_ref->index, true);
     432        } else {
     433                rc = ext4_ialloc_free_inode(fs, inode_ref->index, false);
     434        }
    411435        if (rc != EOK) {
    412436                return rc;
  • uspace/lib/ext4/libext4_filesystem.h

    r08cc26b r304faab  
    6161                ext4_inode_ref_t **);
    6262extern int ext4_filesystem_put_inode_ref(ext4_inode_ref_t *);
    63 extern int ext4_filesystem_alloc_inode(ext4_filesystem_t *, ext4_inode_ref_t **);
    64 extern int ext4_filesystem_init_inode(ext4_filesystem_t *, ext4_inode_ref_t *, int);
     63extern int ext4_filesystem_alloc_inode(ext4_filesystem_t *,
     64                ext4_inode_ref_t **, int);
    6565extern int ext4_filesystem_free_inode(ext4_filesystem_t *, ext4_inode_ref_t *);
    6666extern int ext4_filesystem_truncate_inode(ext4_filesystem_t *,
  • 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/**
  • uspace/lib/ext4/libext4_ialloc.h

    r08cc26b r304faab  
    3737#include "libext4_inode.h"
    3838
    39 extern int ext4_ialloc_free_inode(ext4_filesystem_t *, ext4_inode_ref_t *);
    40 
     39extern int ext4_ialloc_free_inode(ext4_filesystem_t *, uint32_t, bool);
     40extern int ext4_ialloc_alloc_inode(ext4_filesystem_t *, uint32_t *, bool);
    4141#endif
    4242
  • uspace/srv/fs/ext4fs/ext4fs_ops.c

    r08cc26b r304faab  
    394394
    395395        ext4_inode_ref_t *inode_ref;
    396         rc = ext4_filesystem_alloc_inode(inst->filesystem, &inode_ref);
     396        rc = ext4_filesystem_alloc_inode(inst->filesystem, &inode_ref, flags);
    397397        if (rc != EOK) {
    398398                free(enode);
    399399                free(fs_node);
    400                 return rc;
    401         }
    402 
    403         EXT4FS_DBG("inode allocated");
    404         // TODO
    405         return ENOTSUP;
    406 
    407         rc = ext4_filesystem_init_inode(inst->filesystem, inode_ref, flags);
    408         if (rc != EOK) {
    409                 free(enode);
    410                 free(fs_node);
    411                 ext4_filesystem_free_inode(inst->filesystem, inode_ref);
    412400                return rc;
    413401        }
Note: See TracChangeset for help on using the changeset viewer.