Changeset 1a7756a in mainline


Ignore:
Timestamp:
2011-10-12T09:37:59Z (13 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1ccc32f
Parents:
8958a26
Message:

support for reading more complex extents (tree with nonzero depth)

Location:
uspace/lib/ext4
Files:
5 edited

Legend:

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

    r8958a26 r1a7756a  
    5656}
    5757
     58uint32_t ext4_extent_index_get_first_block(ext4_extent_index_t *index)
     59{
     60        return uint32_t_le2host(index->first_block);
     61}
     62
     63uint64_t ext4_extent_index_get_leaf(ext4_extent_index_t *index)
     64{
     65        return ((uint64_t)uint16_t_le2host(index->leaf_hi)) << 32 |
     66                                ((uint64_t)uint32_t_le2host(index->leaf_lo));
     67}
     68
    5869uint16_t ext4_extent_header_get_magic(ext4_extent_header_t *header)
    5970{
  • uspace/lib/ext4/libext4_extent.h

    r8958a26 r1a7756a  
    4949 * It's used at all the levels except the bottom.
    5050 */
    51 typedef struct ext4_extent_idx {
    52         uint32_t block; // Index covers logical blocks from 'block'
     51typedef struct ext4_extent_index {
     52        uint32_t first_block; // Index covers logical blocks from 'block'
    5353        uint32_t leaf_lo; /* Pointer to the physical block of the next
    5454                                           * level. leaf or next index could be there */
    5555        uint16_t leaf_hi;     /* high 16 bits of physical block */
    5656        uint16_t padding;
    57 } ext4_extent_idx_t;
     57} ext4_extent_index_t;
    5858
    5959/*
     
    7171#define EXT4_EXTENT_FIRST(header)       \
    7272                ((ext4_extent_t *) (((void *) (header)) + sizeof(ext4_extent_header_t)))
     73#define EXT4_EXTENT_FIRST_INDEX(header) \
     74                ((ext4_extent_index_t *) (((void *) (header)) + sizeof(ext4_extent_header_t)))
    7375
    7476extern uint32_t ext4_extent_get_first_block(ext4_extent_t *);
    7577extern uint16_t ext4_extent_get_block_count(ext4_extent_t *);
    7678extern uint64_t ext4_extent_get_start(ext4_extent_t *);
     79
     80extern uint32_t ext4_extent_index_get_first_block(ext4_extent_index_t *);
     81extern uint64_t ext4_extent_index_get_leaf(ext4_extent_index_t *);
    7782
    7883extern uint16_t ext4_extent_header_get_magic(ext4_extent_header_t *);
  • uspace/lib/ext4/libext4_filesystem.c

    r8958a26 r1a7756a  
    304304        // TODO check "extents" feature in superblock ???
    305305        if (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_EXTENTS)) {
    306                 current_block = ext4_inode_get_extent_block(inode, iblock);
     306                current_block = ext4_inode_get_extent_block(inode, iblock, fs->device);
    307307                *fblock = current_block;
    308308                return EOK;
  • uspace/lib/ext4/libext4_inode.c

    r8958a26 r1a7756a  
    3737
    3838#include <byteorder.h>
     39#include <errno.h>
     40#include <libblock.h>
    3941#include "libext4.h"
    4042
     
    102104}
    103105
    104 uint32_t ext4_inode_get_extent_block(ext4_inode_t *inode, uint64_t idx)
     106uint32_t ext4_inode_get_extent_block(ext4_inode_t *inode, uint64_t idx, service_id_t service_id)
    105107{
    106108        ext4_extent_header_t *header = ext4_inode_get_extent_header(inode);
     109        ext4_extent_t *extent;
     110        ext4_extent_index_t *extent_index;
    107111
    108         if (ext4_extent_header_get_depth(header) == 0) {
     112        uint32_t first_block;
     113        uint16_t block_count;
     114        uint64_t phys_block = 0;
     115        uint64_t child;
    109116
    110                 ext4_extent_t *extent = EXT4_EXTENT_FIRST(header);
     117        int rc;
     118        block_t* block = NULL;
    111119
    112                 // TODO more effective searching?
     120        while (ext4_extent_header_get_depth(header) != 0) {
     121
     122                extent_index = EXT4_EXTENT_FIRST_INDEX(header);
     123
    113124                for (uint16_t i = 0; i < ext4_extent_header_get_entries_count(header); ++i) {
     125                        if(idx >= ext4_extent_index_get_first_block(extent_index)) {
    114126
    115                         uint32_t first = ext4_extent_get_first_block(extent);
    116                         uint16_t count = ext4_extent_get_block_count(extent);
    117                         uint64_t block = 0;
     127                                child = ext4_extent_index_get_leaf(extent_index);
    118128
    119                         if ((idx >= first) && (idx < first + count)) {
    120                                 block = ext4_extent_get_start(extent) + idx;
    121                                 block -= ext4_extent_get_first_block(extent);
    122                                 return block;
     129                                if (block != NULL) {
     130                                        block_put(block);
     131                                }
     132
     133                                rc = block_get(&block, service_id, child, BLOCK_FLAGS_NONE);
     134                                if (rc != EOK) {
     135                                        return 0;
     136                                }
     137                                EXT4FS_DBG("get block");
     138
     139
     140                                header = (ext4_extent_header_t *)block->data;
     141                                break;
    123142                        }
    124                         // Go to the next extent
    125                         ++extent;
    126143                }
    127144        }
    128145
    129         // TODO binary search for depth > 0
    130         EXT4FS_DBG("NOT IMPLEMENTED !!!");
    131         return 0;
     146        extent = EXT4_EXTENT_FIRST(header);
    132147
     148        for (uint16_t i = 0; i < ext4_extent_header_get_entries_count(header); ++i) {
     149
     150                first_block = ext4_extent_get_first_block(extent);
     151                block_count = ext4_extent_get_block_count(extent);
     152
     153                if ((idx >= first_block) && (idx < first_block + block_count)) {
     154                        phys_block = ext4_extent_get_start(extent) + idx;
     155                        phys_block -= ext4_extent_get_first_block(extent);
     156
     157                        // Memory leak prevention
     158                        if (block != NULL) {
     159                                block_put(block);
     160                        }
     161                        return phys_block;
     162                }
     163                // Go to the next extent
     164                ++extent;
     165        }
     166
     167
     168        EXT4FS_DBG("ERROR - reached function end");
     169        return phys_block;
    133170}
    134171
  • uspace/lib/ext4/libext4_inode.h

    r8958a26 r1a7756a  
    168168uint32_t ext4_inode_get_direct_block(ext4_inode_t *, uint8_t);
    169169uint32_t ext4_inode_get_indirect_block(ext4_inode_t *, uint8_t);
    170 uint32_t ext4_inode_get_extent_block(ext4_inode_t *, uint64_t);
     170uint32_t ext4_inode_get_extent_block(ext4_inode_t *, uint64_t, service_id_t);
    171171/*
    172172uint32_t blocks[EXT4_INODE_BLOCKS]; // Pointers to blocks
Note: See TracChangeset for help on using the changeset viewer.