Changeset f8c60f5 in mainline for uspace/lib/ext2/libext2_filesystem.c


Ignore:
Timestamp:
2011-03-09T21:59:30Z (13 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c3f95d8
Parents:
66bea243
Message:

Basic sketch of code for allocating blocks

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ext2/libext2_filesystem.c

    r66bea243 rf8c60f5  
    384384
    385385/**
     386 * Allocate a given number of blocks and store their ids in blocks
     387 *
     388 * @param fs pointer to filesystem
     389 * @param blocks array of count uint32_t values where store block ids
     390 * @param count number of blocks to allocate and elements in blocks array
     391 * @param preferred_bg preferred block group number
     392 *
     393 * @return              EOK on success or negative error code on failure
     394 */
     395int ext2_filesystem_allocate_blocks(ext2_filesystem_t *fs, uint32_t *blocks,
     396    size_t count, uint32_t preferred_bg)
     397{
     398        uint32_t bg_count = ext2_superblock_get_block_group_count(fs->superblock);
     399        uint32_t bpg = ext2_superblock_get_blocks_per_group(fs->superblock);
     400        uint32_t block_size = ext2_superblock_get_block_size(fs->superblock);
     401        uint32_t block_group = preferred_bg;
     402        uint32_t free_blocks_sb;
     403        uint32_t block_groups_left;
     404        size_t idx;
     405        ext2_block_group_ref_t *bg;
     406        int rc;
     407        uint32_t bb_block;
     408        block_t *block;
     409        size_t bb_idx;
     410        size_t bb_bit;
     411       
     412        free_blocks_sb = ext2_superblock_get_free_block_count(fs->superblock);
     413       
     414        if (count > free_blocks_sb) {
     415                return EIO;
     416        }
     417       
     418        block_groups_left = bg_count;
     419       
     420        idx = 0;
     421       
     422        // Read the block group descriptor
     423        rc = ext2_filesystem_get_block_group_ref(fs, block_group, &bg);
     424        if (rc != EOK) {
     425                goto failed;
     426        }
     427       
     428        while (idx < count && block_groups_left > 0) {
     429                uint16_t fb = ext2_block_group_get_free_block_count(bg->block_group);
     430                if (fb == 0) {
     431                        block_group = (block_group + 1) % bg_count;
     432                        block_groups_left -= 1;
     433                       
     434                        rc = ext2_filesystem_put_block_group_ref(bg);
     435                        if (rc != EOK) {
     436                                goto failed;
     437                        }
     438                       
     439                        rc = ext2_filesystem_get_block_group_ref(fs, block_group, &bg);
     440                        if (rc != EOK) {
     441                                goto failed;
     442                        }
     443                        continue;
     444                }
     445               
     446                // We found a block group with free block, let's look at the block bitmap
     447                bb_block = ext2_block_group_get_block_bitmap_block(bg->block_group);
     448               
     449                rc = block_get(&block, fs->device, bb_block, BLOCK_FLAGS_NONE);
     450                if (rc != EOK) {
     451                        goto failed;
     452                }
     453               
     454                // Use all blocks from this block group
     455                for (bb_idx = 0; bb_idx < block_size && idx < count; bb_idx++) {
     456                        uint8_t *data = (uint8_t *) block->data;
     457                        if (data[bb_idx] == 0xff) {
     458                                continue;
     459                        }
     460                        // find an empty bit
     461                        uint8_t mask;
     462                        for (mask = 1, bb_bit = 0;
     463                                 bb_bit < 8 && idx < count;
     464                                 bb_bit++, mask = mask << 1) {
     465                                if ((data[bb_idx] & mask) == 0) {
     466                                        // free block found
     467                                        blocks[idx] = block_group * bpg + bb_idx*8 + bb_bit;
     468                                        data[bb_idx] |= mask;
     469                                        idx += 1;
     470                                        fb -= 1;
     471                                        ext2_block_group_set_free_block_count(bg->block_group, fb);
     472                                }
     473                        }
     474                }
     475        }
     476       
     477        rc = ext2_filesystem_put_block_group_ref(bg);
     478        if (rc != EOK) {
     479                goto failed;
     480        }
     481       
     482        // TODO update superblock
     483       
     484        return EOK;
     485failed:
     486        // TODO deallocate already allocated blocks, if possible
     487       
     488        return rc;
     489}
     490
     491/**
    386492 * Finalize an instance of filesystem
    387493 *
Note: See TracChangeset for help on using the changeset viewer.