Changeset 1c1c736 in mainline


Ignore:
Timestamp:
2011-11-08T13:05:43Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0f09d4ea
Parents:
e31e56a1
Message:

not functional block allocation + write operation skeleton

Location:
uspace
Files:
3 edited

Legend:

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

    re31e56a1 r1c1c736  
    5454}
    5555
     56static int ext4_bitmap_find_free_bit_and_set(uint8_t *bitmap, uint32_t *index, uint32_t size)
     57{
     58        uint8_t *pos = bitmap;
     59        int i;
     60        uint32_t idx = 0;
     61
     62        while (pos < bitmap + size) {
     63                if ((*pos & 255) != 255) {
     64                        // free bit found
     65                        break;
     66                }
     67
     68                ++pos;
     69                idx += 8;
     70        }
     71
     72        if (pos < bitmap + size) {
     73
     74                for(i = 0; i < 8; ++i) {
     75                        if ((*pos & (1 << i)) == 0) {
     76                                // free bit found
     77                                *pos |= (1 << i);
     78                                *index = idx;
     79                                return EOK;
     80                        }
     81
     82                        idx++;
     83                }
     84        }
     85
     86        return ENOSPC;
     87}
     88
    5689int ext4_bitmap_free_block(ext4_filesystem_t *fs, uint32_t block_index)
    5790{
     
    93126        bg_ref->dirty = true;
    94127
     128        // TODO change free blocks count in superblock
     129
    95130        rc = ext4_filesystem_put_block_group_ref(bg_ref);
    96131        if (rc != EOK) {
     
    102137}
    103138
     139int ext4_bitmap_alloc_block(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref, uint32_t *fblock)
     140{
     141        int rc;
     142        uint32_t inodes_per_group, block_group, blocks_per_group;
     143        ext4_block_group_ref_t *bg_ref;
     144        uint32_t bitmap_block;
     145        block_t *block;
     146        uint32_t rel_block_idx = 0;
     147        uint32_t block_size;
     148
     149        inodes_per_group = ext4_superblock_get_inodes_per_group(fs->superblock);
     150        block_group = inode_ref->index / inodes_per_group;
     151
     152        block_size = ext4_superblock_get_block_size(fs->superblock);
     153
     154        rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
     155        if (rc != EOK) {
     156                return rc;
     157        }
     158
     159        bitmap_block = ext4_block_group_get_block_bitmap(bg_ref->block_group);
     160
     161        rc = block_get(&block, fs->device, bitmap_block, 0);
     162        if (rc != EOK) {
     163                ext4_filesystem_put_block_group_ref(bg_ref);
     164                return rc;
     165        }
     166
     167        rc = ext4_bitmap_find_free_bit_and_set(block->data, &rel_block_idx, block_size);
     168
     169        // if ENOSPC - try next block group - try next block groups
     170
     171
     172
     173
     174        // TODO decrement superblock & block group free blocks count
     175
     176        // return
     177        blocks_per_group = ext4_superblock_get_blocks_per_group(fs->superblock);
     178        *fblock = blocks_per_group * block_group + rel_block_idx;
     179        return EOK;
     180
     181}
    104182
    105183/**
  • uspace/lib/ext4/libext4_bitmap.h

    re31e56a1 r1c1c736  
    3838
    3939extern int ext4_bitmap_free_block(ext4_filesystem_t *, uint32_t);
    40 
     40extern int ext4_bitmap_alloc_block(ext4_filesystem_t *,
     41                ext4_inode_ref_t *, uint32_t *);
    4142#endif
    4243
  • uspace/srv/fs/ext4fs/ext4fs_ops.c

    re31e56a1 r1c1c736  
    926926    size_t *wbytes, aoff64_t *nsize)
    927927{
    928         EXT4FS_DBG("not supported");
    929 
    930         // TODO
    931         return ENOTSUP;
     928        EXT4FS_DBG("");
     929
     930        int rc;
     931        fs_node_t *fn;
     932        ext4fs_node_t *enode;
     933        ext4_filesystem_t *fs;
     934        ext4_inode_ref_t *inode_ref;
     935        ipc_callid_t callid;
     936        size_t len, bytes, block_size;
     937        block_t *write_block;
     938        uint32_t fblock, iblock;
     939
     940        rc = ext4fs_node_get(&fn, service_id, index);
     941        if (rc != EOK) {
     942                return rc;
     943        }
     944
     945        if (!async_data_write_receive(&callid, &len)) {
     946                rc = EINVAL;
     947                ext4fs_node_put(fn);
     948                async_answer_0(callid, rc);
     949                return rc;
     950        }
     951
     952
     953        enode = EXT4FS_NODE(fn);
     954        inode_ref = enode->inode_ref;
     955        fs = enode->instance->filesystem;
     956
     957        block_size = ext4_superblock_get_block_size(fs->superblock);
     958
     959        // Prevent writing to more than one block
     960        bytes = min(len, block_size - (pos % block_size));
     961
     962        EXT4FS_DBG("bytes == \%u", bytes);
     963
     964        iblock =  pos / block_size;
     965
     966        rc = ext4_filesystem_get_inode_data_block_index(fs, inode_ref->inode, iblock, &fblock);
     967
     968
     969        // TODO allocation if fblock == 0
     970        if (fblock == 0) {
     971                EXT4FS_DBG("Allocate block !!!");
     972
     973                return ENOTSUP;
     974        }
     975
     976        // TODO flags
     977        rc = block_get(&write_block, service_id, fblock, 0);
     978        if (rc != EOK) {
     979                ext4fs_node_put(fn);
     980                async_answer_0(callid, rc);
     981                return rc;
     982        }
     983
     984        /*
     985        if (flags == BLOCK_FLAGS_NOREAD)
     986                memset(b->data, 0, sbi->block_size);
     987        */
     988
     989        async_data_write_finalize(callid, write_block->data + (pos % block_size), bytes);
     990        write_block->dirty = true;
     991
     992        rc = block_put(write_block);
     993        if (rc != EOK) {
     994                ext4fs_node_put(fn);
     995                return rc;
     996        }
     997
     998        /*
     999        if (pos + bytes > ino_i->i_size) {
     1000                ino_i->i_size = pos + bytes;
     1001                ino_i->dirty = true;
     1002        }
     1003        *nsize = ino_i->i_size;
     1004        *wbytes = bytes;
     1005        */
     1006        return ext4fs_node_put(fn);
    9321007}
    9331008
     
    9571032        if (! ext4_inode_can_truncate(fs->superblock, inode_ref->inode)) {
    9581033                // Unable to truncate
     1034                ext4fs_node_put(fn);
    9591035                return EINVAL;
    9601036        }
     
    9631039
    9641040        if (old_size == new_size) {
    965                 rc = EOK;
     1041                ext4fs_node_put(fn);
     1042                return EOK;
    9661043        } else {
    9671044
     
    10051082
    10061083        ext4fs_node_put(fn);
    1007         return rc;
     1084
     1085        return EOK;
    10081086}
    10091087
Note: See TracChangeset for help on using the changeset viewer.