Changeset 052e82d in mainline


Ignore:
Timestamp:
2011-11-07T11:50:31Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update
Children:
12b4a7f
Parents:
5664cf64
Message:

partially functional truncate operation

Location:
uspace
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ext4/Makefile

    r5664cf64 r052e82d  
    3333
    3434SOURCES = \
     35        libext4_bitmap.c \
    3536        libext4_block_group.c \
    3637        libext4_directory.c \
  • uspace/lib/ext4/libext4.h

    r5664cf64 r052e82d  
    3434#define LIBEXT4_LIBEXT4_H_
    3535
     36#include "libext4_bitmap.h"
    3637#include "libext4_block_group.h"
    3738#include "libext4_directory.h"
  • uspace/lib/ext4/libext4_block_group.c

    r5664cf64 r052e82d  
    6363}
    6464
     65void ext4_block_group_set_free_blocks_count(ext4_block_group_t *bg, uint32_t value) {
     66        bg->free_blocks_count_lo = host2uint16_t_le((value << 16) >> 16);
     67        bg->free_blocks_count_hi = host2uint16_t_le(value >> 16);
     68}
     69
    6570uint32_t ext4_block_group_get_free_inodes_count(ext4_block_group_t *bg)
    6671{
  • uspace/lib/ext4/libext4_block_group.h

    r5664cf64 r052e82d  
    7373extern uint64_t ext4_block_group_get_inode_table_first_block(ext4_block_group_t *);
    7474extern uint32_t ext4_block_group_get_free_blocks_count(ext4_block_group_t *);
     75extern void ext4_block_group_set_free_blocks_count(ext4_block_group_t *, uint32_t);
    7576extern uint32_t ext4_block_group_get_free_inodes_count(ext4_block_group_t *);
    7677extern uint32_t ext4_block_group_get_used_dirs_count(ext4_block_group_t *);
  • uspace/lib/ext4/libext4_filesystem.c

    r5664cf64 r052e82d  
    251251         */
    252252        newref->index = index+1;
     253        newref->dirty = false;
    253254
    254255        *ref = newref;
     
    261262{
    262263        int rc;
     264
     265        if (ref->dirty) {
     266                ref->block->dirty = true;
     267        }
    263268
    264269        rc = block_put(ref->block);
     
    355360
    356361
    357 int ext4_filesystem_release_inode_block(ext4_filesystem_t *fs, ext4_inode_t *inode, uint32_t iblock)
     362int ext4_filesystem_release_inode_block(ext4_filesystem_t *fs,
     363                ext4_inode_ref_t *inode_ref, uint32_t iblock)
    358364{
    359365        int rc;
    360366        uint32_t fblock;
    361 
    362         // TODO handle with extents
    363 
    364         rc = ext4_filesystem_get_inode_data_block_index(fs, inode, iblock, &fblock);
    365         if (rc != EOK) {
    366                 // TODO error
    367                 return rc;
    368         }
    369 
    370         // Sparse file
    371         if (fblock == 0) {
    372 
    373                 //
    374                 return EOK;
    375         }
    376 
    377 
    378         // TODO vyhledat policko s ukazatelem a nastavit nulu
    379 
    380 
    381         // TODO uvolnit blok v bitmape
    382 
    383         // TODO return
    384 
    385 
    386         return EOK;
     367        int i;
     368        int level;
     369        aoff64_t block_offset_in_level;
     370        uint32_t current_block;
     371        uint32_t offset_in_block;
     372        block_t *block;
     373        ext4_inode_t *inode = inode_ref->inode;
     374
     375        /* TODO handle extents */
     376
     377        /* Handle simple case when we are dealing with direct reference */
     378        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
     379                EXT4FS_DBG("direct block");
     380                fblock = ext4_inode_get_direct_block(inode, (uint32_t)iblock);
     381                // Sparse file
     382                if (fblock == 0) {
     383                        return EOK;
     384                }
     385
     386                ext4_inode_set_direct_block(inode, iblock, 0);
     387                return ext4_bitmap_free_block(fs, fblock);
     388        } else {
     389
     390                /* Determine the indirection level needed to get the desired block */
     391                level = -1;
     392                for (i = 1; i < 4; i++) {
     393                        if (iblock < fs->inode_block_limits[i]) {
     394                                level = i;
     395                                break;
     396                        }
     397                }
     398
     399                if (level == -1) {
     400                        return EIO;
     401                }
     402
     403                /* Compute offsets for the topmost level */
     404                block_offset_in_level = iblock - fs->inode_block_limits[level-1];
     405                current_block = ext4_inode_get_indirect_block(inode, level-1);
     406                offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
     407
     408                /* Navigate through other levels, until we find the block number
     409                 * or find null reference meaning we are dealing with sparse file
     410                 */
     411                while (level > 0) {
     412                        rc = block_get(&block, fs->device, current_block, 0);
     413                        if (rc != EOK) {
     414                                return rc;
     415                        }
     416
     417                        current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]);
     418
     419                        // Set zero
     420                        if (level == 1) {
     421                                ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(0);
     422                                block->dirty = true;
     423                        }
     424
     425                        rc = block_put(block);
     426                        if (rc != EOK) {
     427                                return rc;
     428                        }
     429
     430                        level -= 1;
     431
     432                        /* If we are on the last level, break here as
     433                         * there is no next level to visit
     434                         */
     435                        if (level == 0) {
     436                                break;
     437                        }
     438
     439                        /* Visit the next level */
     440                        block_offset_in_level %= fs->inode_blocks_per_level[level];
     441                        offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
     442                }
     443
     444                fblock = current_block;
     445
     446                if (fblock == 0) {
     447                        return EOK;
     448                }
     449        }
     450
     451        return ext4_bitmap_free_block(fs, fblock);
     452
    387453}
    388454
  • uspace/lib/ext4/libext4_filesystem.h

    r5664cf64 r052e82d  
    6363        ext4_inode_t *, aoff64_t iblock, uint32_t *);
    6464extern int ext4_filesystem_release_inode_block(ext4_filesystem_t *,
    65                 ext4_inode_t *, uint32_t);
     65                ext4_inode_ref_t *, uint32_t);
    6666#endif
    6767
  • uspace/lib/ext4/libext4_inode.c

    r5664cf64 r052e82d  
    6767                return ((uint64_t)uint32_t_le2host(inode->size_hi)) << 32 |
    6868                            ((uint64_t)uint32_t_le2host(inode->size_lo));
    69                 }
     69        }
    7070        return uint32_t_le2host(inode->size_lo);
     71}
     72
     73void ext4_inode_set_size(ext4_inode_t *inode, uint64_t value) {
     74        inode->size_lo = host2uint32_t_le((value << 32) >> 32);
     75        inode->size_hi = host2uint32_t_le(value >> 32);
    7176}
    7277
  • uspace/lib/ext4/libext4_inode.h

    r5664cf64 r052e82d  
    144144        ext4_inode_t *inode;
    145145        uint32_t index; // Index number of this inode
     146        bool dirty;
    146147} ext4_inode_ref_t;
    147148
     
    153154*/
    154155extern uint64_t ext4_inode_get_size(ext4_superblock_t *, ext4_inode_t *);
     156extern void ext4_inode_set_size(ext4_inode_t *, uint64_t);
    155157/*
    156158extern uint32_t ext4_inode_get_access_time(ext4_inode_t *);
  • uspace/srv/fs/ext4fs/ext4fs_ops.c

    r5664cf64 r052e82d  
    939939        fs_node_t *fn;
    940940        ext4fs_node_t *enode;
    941         ext4_inode_t *inode;
     941        ext4_inode_ref_t *inode_ref;
    942942        ext4_filesystem_t* fs;
    943943        aoff64_t old_size;
     
    951951
    952952        enode = EXT4FS_NODE(fn);
    953         inode = enode->inode_ref->inode;
     953        inode_ref = enode->inode_ref;
    954954        fs = enode->instance->filesystem;
    955955
    956         old_size = ext4_inode_get_size(fs->superblock, inode);
     956        old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
    957957
    958958        printf("old size = \%llu, new size = \%llu\n", old_size, new_size);
     
    961961                rc = EOK;
    962962        } else {
    963                 /** AAAAAAAAAAAAAAAAAAAA */
    964963
    965964                //int rc;
     
    989988                }
    990989
    991                 // TODO dirty add to inode_ref_t
    992                 //ino_i->dirty = true;
     990                inode_ref->dirty = true;
    993991
    994992                for (i = 0; i< blocks_count; ++i) {
    995993                        // TODO check retval
    996                         ext4_filesystem_release_inode_block(fs, inode, total_blocks - i);
    997                         // TODO subtract inode->size
    998                 }
    999 
    1000                 /** BBBBBBBBBBBBBBBBBBBB */
     994                        ext4_filesystem_release_inode_block(fs, inode_ref, total_blocks - i);
     995                }
     996
     997                ext4_inode_set_size(inode_ref->inode, new_size);
    1001998
    1002999        }
Note: See TracChangeset for help on using the changeset viewer.