Changeset cd1cc4e6 in mainline


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

bugfixes of inode allocation and link operation

Location:
uspace
Files:
4 edited

Legend:

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

    r786bd56 rcd1cc4e6  
    9595}
    9696
     97uint8_t ext4_directory_entry_ll_get_inode_type(
     98                ext4_superblock_t *sb, ext4_directory_entry_ll_t *de)
     99{
     100        if (ext4_superblock_get_rev_level(sb) == 0 &&
     101                    ext4_superblock_get_minor_rev_level(sb) < 5) {
     102
     103                        return de->inode_type;
     104        }
     105
     106        return EXT4_DIRECTORY_FILETYPE_UNKNOWN;
     107
     108}
     109
     110void ext4_directory_entry_ll_set_inode_type(
     111                ext4_superblock_t *sb, ext4_directory_entry_ll_t *de, uint8_t type)
     112{
     113        if (ext4_superblock_get_rev_level(sb) == 0 &&
     114                        ext4_superblock_get_minor_rev_level(sb) < 5) {
     115
     116                de->inode_type = type;
     117        }
     118
     119        // else do nothing
     120
     121}
    97122
    98123int ext4_directory_iterator_init(ext4_directory_iterator_t *it,
     
    261286
    262287int ext4_directory_add_entry(ext4_filesystem_t *fs, ext4_inode_ref_t * inode_ref,
    263                 const char *entry_name, uint32_t child_inode)
    264 {
     288                const char *entry_name, ext4_inode_ref_t *child)
     289{
     290        EXT4FS_DBG("adding dentry \%s to inode \%u", entry_name, child->index);
     291
    265292        int rc;
    266293
     
    283310
    284311                        // Don't touch entry length
    285                         ext4_directory_entry_ll_set_inode(it.current, child_inode);
     312                        ext4_directory_entry_ll_set_inode(it.current, child->index);
    286313                        ext4_directory_entry_ll_set_name_length(fs->superblock, it.current, name_len);
    287314                        it.current_block->dirty = true;
     
    290317
    291318                if (entry_inode != 0) {
    292 
    293319                        uint16_t used_name_len = ext4_directory_entry_ll_get_name_length(
    294320                                        fs->superblock, it.current);
    295321                        uint16_t free_space = rec_len - 8 - (used_name_len + (4- used_name_len % 4));
    296322
     323                        EXT4FS_DBG("rec_len = \%u, free_space == \%u, required_len = \%u", rec_len, free_space, required_len);
     324
    297325                        if (free_space >= required_len) {
    298326                                uint16_t used_len = rec_len - free_space;
     
    301329                                ext4_directory_entry_ll_set_entry_length(it.current, used_len);
    302330
    303                                 // Jump to newly created
    304                                 rc = ext4_directory_iterator_next(&it);
    305                                 if (rc != EOK) {
    306                                         return rc;
    307                                 }
     331                                // SEEK manually
     332                                it.current_offset += used_len;
     333                                ext4_directory_entry_ll_t *new_entry = it.current_block->data + it.current_offset;
    308334
    309335                                // We are sure, that both entries are in the same data block
    310336                                // dirtyness will be set now
    311337
    312                                 ext4_directory_entry_ll_set_inode(it.current, child_inode);
    313                                 ext4_directory_entry_ll_set_entry_length(it.current, free_space);
     338                                ext4_directory_entry_ll_set_inode(new_entry, child->index);
     339                                ext4_directory_entry_ll_set_entry_length(new_entry, free_space);
    314340                                ext4_directory_entry_ll_set_name_length(
    315                                                 fs->superblock, it.current, name_len);
    316                                 memcpy(it.current->name, entry_name, name_len);
     341                                                fs->superblock, new_entry, name_len);
     342
     343                                if (ext4_inode_is_type(fs->superblock, child->inode, EXT4_INODE_MODE_DIRECTORY)) {
     344                                        ext4_directory_entry_ll_set_inode_type(
     345                                                        fs->superblock, new_entry, EXT4_DIRECTORY_FILETYPE_DIR);
     346                                } else {
     347                                        ext4_directory_entry_ll_set_inode_type(
     348                                                        fs->superblock, new_entry, EXT4_DIRECTORY_FILETYPE_REG_FILE);
     349                                }
     350
     351                                memcpy(new_entry->name, entry_name, name_len);
    317352                                it.current_block->dirty = true;
    318353                                return ext4_directory_iterator_fini(&it);
     
    367402
    368403        // Entry length is not affected
    369         ext4_directory_entry_ll_set_inode(it.current, child_inode);
     404        ext4_directory_entry_ll_set_inode(it.current, child->index);
    370405        ext4_directory_entry_ll_set_name_length(fs->superblock, it.current, name_len);
    371406        memcpy(it.current->name, entry_name, name_len);
  • uspace/lib/ext4/libext4_directory.h

    r786bd56 rcd1cc4e6  
    3939#define EXT4_DIRECTORY_FILENAME_LEN     255
    4040
     41#define EXT4_DIRECTORY_FILETYPE_UNKNOWN         0
     42#define EXT4_DIRECTORY_FILETYPE_REG_FILE        1
     43#define EXT4_DIRECTORY_FILETYPE_DIR             2
     44#define EXT4_DIRECTORY_FILETYPE_CHRDEV          3
     45#define EXT4_DIRECTORY_FILETYPE_BLKDEV          4
     46#define EXT4_DIRECTORY_FILETYPE_FIFO            5
     47#define EXT4_DIRECTORY_FILETYPE_SOCK            6
     48#define EXT4_DIRECTORY_FILETYPE_SYMLINK         7
     49
    4150/**
    4251 * Linked list directory entry structure
     
    7382extern void ext4_directory_entry_ll_set_name_length(ext4_superblock_t *,
    7483                ext4_directory_entry_ll_t *, uint16_t);
     84extern uint8_t ext4_directory_entry_ll_get_inode_type(ext4_superblock_t *,
     85                ext4_directory_entry_ll_t *);
     86extern void ext4_directory_entry_ll_set_inode_type(ext4_superblock_t *,
     87                ext4_directory_entry_ll_t *, uint8_t);
    7588
    7689extern int ext4_directory_iterator_init(ext4_directory_iterator_t *,
     
    8194
    8295extern int ext4_directory_add_entry(ext4_filesystem_t *, ext4_inode_ref_t *,
    83                 const char *, uint32_t);
     96                const char *, ext4_inode_ref_t *);
    8497extern int ext4_directory_find_entry(ext4_directory_iterator_t *,
    8598                ext4_inode_ref_t *, const char *);
  • uspace/lib/ext4/libext4_ialloc.c

    r786bd56 rcd1cc4e6  
    4747}
    4848
     49static uint32_t ext4_ialloc_index_in_group2inode(ext4_superblock_t *sb,
     50                uint32_t index, uint32_t bgid)
     51{
     52        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
     53        return bgid * inodes_per_group + (index + 1);
     54}
     55
    4956static uint32_t ext4_ialloc_get_bgid_of_inode(ext4_superblock_t *sb,
    5057                uint32_t inode)
     
    127134        uint32_t bgid = 0;
    128135        uint32_t bg_count = ext4_superblock_get_block_group_count(sb);
     136        uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
     137        uint32_t avg_free_inodes = sb_free_inodes / bg_count;
    129138
    130139        while (bgid < bg_count) {
     140
     141                EXT4FS_DBG("testing bg \%u", bgid);
    131142
    132143                ext4_block_group_ref_t *bg_ref;
     
    141152                uint32_t used_dirs = ext4_block_group_get_used_dirs_count(bg, sb);
    142153
    143                 if ((free_inodes > 0) && (free_blocks > 0)) {
    144 
    145                         uint32_t bitmap_block_addr =  ext4_block_group_get_block_bitmap(
     154                if ((free_inodes >= avg_free_inodes) && (free_blocks > 0)) {
     155
     156                        uint32_t bitmap_block_addr =  ext4_block_group_get_inode_bitmap(
    146157                                        bg_ref->block_group, sb);
    147158
     
    155166                        // Alloc bit
    156167                        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                         }
     168                        uint32_t index_in_group;
     169                        rc = ext4_bitmap_find_free_bit_and_set(
     170                                        bitmap_block->data, 0, &index_in_group, inodes_in_group);
     171//                      if (rc == ENOSPC) {
     172//                              block_put(bitmap_block);
     173//                              ext4_filesystem_put_block_group_ref(bg_ref);
     174//                              continue;
     175//                      }
    163176
    164177                        bitmap_block->dirty = true;
     
    174187
    175188                        if (is_dir) {
    176                                 used_dirs--;
     189                                used_dirs++;
    177190                                ext4_block_group_set_used_dirs_count(bg, sb, used_dirs);
    178191                        }
     
    183196                        if (rc != EOK) {
    184197                                // TODO
    185                         }
    186 
    187                         uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
     198                                EXT4FS_DBG("ERRRRR");
     199                        }
     200
    188201                        sb_free_inodes--;
    189202                        ext4_superblock_set_free_inodes_count(sb, sb_free_inodes);
    190203
     204                        *index = ext4_ialloc_index_in_group2inode(sb, index_in_group, bgid);
     205
    191206                        return EOK;
    192207
    193                 } else {
    194                         // Not modified
    195                         ext4_filesystem_put_block_group_ref(bg_ref);
    196208                }
    197209
     210                // Not modified
     211                ext4_filesystem_put_block_group_ref(bg_ref);
     212                ++bgid;
    198213        }
    199214
  • uspace/srv/fs/ext4fs/ext4fs_ops.c

    r786bd56 rcd1cc4e6  
    401401        }
    402402
     403        EXT4FS_DBG("allocated");
     404
    403405        enode->inode_ref = inode_ref;
    404406        enode->instance = inst;
     
    424426        *rfn = fs_node;
    425427
     428        EXT4FS_DBG("finished");
     429
    426430        // TODO
    427431        return EOK;
     
    431435int ext4fs_destroy_node(fs_node_t *fn)
    432436{
     437        EXT4FS_DBG("");
    433438        int rc;
    434439
     
    480485int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
    481486{
     487        EXT4FS_DBG("");
     488
    482489        int rc;
    483490
     
    487494        }
    488495
     496        EXT4FS_DBG("name checked");
     497
    489498        ext4fs_node_t *parent = EXT4FS_NODE(pfn);
    490499        ext4fs_node_t *child = EXT4FS_NODE(cfn);
     
    492501
    493502        // Add entry to parent directory
    494         rc = ext4_directory_add_entry(fs, parent->inode_ref, name, child->inode_ref->index);
    495         if (rc != EOK) {
    496                 return rc;
    497         }
     503        rc = ext4_directory_add_entry(fs, parent->inode_ref, name, child->inode_ref);
     504        if (rc != EOK) {
     505                return rc;
     506        }
     507
     508        EXT4FS_DBG("dentry added");
    498509
    499510        // Fill new dir -> add '.' and '..' entries
    500511        if (ext4_inode_is_type(fs->superblock, child->inode_ref->inode, EXT4_INODE_MODE_DIRECTORY)) {
    501512
    502                 rc = ext4_directory_add_entry(fs, child->inode_ref, ".", child->inode_ref->index);
     513                rc = ext4_directory_add_entry(fs, child->inode_ref, ".", child->inode_ref);
    503514                if (rc != EOK) {
    504515                        ext4_directory_remove_entry(fs, parent->inode_ref, name);
     
    506517                }
    507518
    508                 rc = ext4_directory_add_entry(fs, child->inode_ref, "..", parent->inode_ref->index);
     519                EXT4FS_DBG("added dot");
     520
     521                rc = ext4_directory_add_entry(fs, child->inode_ref, "..", parent->inode_ref);
    509522                if (rc != EOK) {
    510523                        ext4_directory_remove_entry(fs, parent->inode_ref, name);
     
    512525                        return rc;
    513526                }
     527
     528                EXT4FS_DBG("added dotdot");
    514529
    515530                uint16_t parent_links = ext4_inode_get_links_count(parent->inode_ref->inode);
Note: See TracChangeset for help on using the changeset viewer.