Changeset 3d4fd2c in mainline for uspace/lib/ext4


Ignore:
Timestamp:
2011-11-22T16:56:09Z (14 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
82d7816
Parents:
bf66ef4
Message:

deleting regular files (directories is not debugged)

Location:
uspace/lib/ext4
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ext4/libext4.h

    rbf66ef4 r3d4fd2c  
    4242#include "libext4_filesystem.h"
    4343#include "libext4_hash.h"
     44#include "libext4_ialloc.h"
    4445#include "libext4_inode.h"
    4546#include "libext4_superblock.h"
  • uspace/lib/ext4/libext4_filesystem.c

    rbf66ef4 r3d4fd2c  
    283283}
    284284
     285int ext4_filesystem_free_inode(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref)
     286{
     287        int rc;
     288        // release all indirect blocks
     289
     290        uint32_t fblock;
     291
     292        // 1) Single indirect
     293        fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0);
     294        if (fblock != 0) {
     295                rc = ext4_balloc_free_block(fs, inode_ref, fblock);
     296                if (rc != EOK) {
     297                        // TODO error
     298                }
     299
     300                ext4_inode_set_indirect_block(inode_ref->inode, 0, 0);
     301        }
     302
     303        block_t *block;
     304        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
     305        uint32_t count = block_size / sizeof(uint32_t);
     306
     307        // 2) Double indirect
     308        fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1);
     309        if (fblock != 0) {
     310                rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
     311                if (rc != EOK) {
     312                        // TODO error
     313                }
     314
     315                uint32_t ind_block;
     316                for (uint32_t offset = 0; offset < count; ++offset) {
     317                        ind_block = uint32_t_le2host(((uint32_t*)block->data)[offset]);
     318
     319                        if (ind_block != 0) {
     320                                rc = ext4_balloc_free_block(fs, inode_ref, ind_block);
     321                                if (rc != EOK) {
     322                                        // TODO error
     323                                }
     324                        }
     325                }
     326
     327                block_put(block);
     328                rc = ext4_balloc_free_block(fs, inode_ref, fblock);
     329                if (rc != EOK) {
     330                        // TODO error
     331                }
     332
     333                ext4_inode_set_indirect_block(inode_ref->inode, 1, 0);
     334        }
     335
     336
     337        // 3) Tripple indirect
     338        block_t *subblock;
     339        fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2);
     340        if (fblock != 0) {
     341                rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
     342                if (rc != EOK) {
     343                        // TODO error
     344                }
     345
     346                uint32_t ind_block;
     347                for (uint32_t offset = 0; offset < count; ++offset) {
     348                        ind_block = uint32_t_le2host(((uint32_t*)block->data)[offset]);
     349
     350                        if (ind_block != 0) {
     351                                rc = block_get(&subblock, fs->device, ind_block, BLOCK_FLAGS_NONE);
     352                                if (rc != EOK) {
     353                                        // TODO error
     354                                }
     355
     356                                uint32_t ind_subblock;
     357                                for (uint32_t suboffset = 0; suboffset < count; ++suboffset) {
     358                                        ind_subblock = uint32_t_le2host(((uint32_t*)subblock->data)[suboffset]);
     359
     360                                        if (ind_subblock != 0) {
     361                                                rc = ext4_balloc_free_block(fs, inode_ref, ind_subblock);
     362                                                if (rc != EOK) {
     363                                                        // TODO error
     364                                                }
     365                                        }
     366
     367                                }
     368                                block_put(subblock);
     369
     370                        }
     371
     372                        rc = ext4_balloc_free_block(fs, inode_ref, ind_block);
     373                        if (rc != EOK) {
     374                                // TODO error
     375                        }
     376
     377
     378                }
     379
     380                block_put(block);
     381                rc = ext4_balloc_free_block(fs, inode_ref, fblock);
     382                if (rc != EOK) {
     383                        // TODO error
     384                }
     385
     386                ext4_inode_set_indirect_block(inode_ref->inode, 2, 0);
     387        }
     388
     389        // Free inode
     390        rc = ext4_ialloc_free_inode(fs, inode_ref);
     391        if (rc != EOK) {
     392                return rc;
     393        }
     394
     395        return EOK;
     396}
     397
     398int ext4_filesystem_truncate_inode(ext4_filesystem_t *fs,
     399                ext4_inode_ref_t *inode_ref, aoff64_t new_size)
     400{
     401        aoff64_t old_size;
     402        aoff64_t size_diff;
     403
     404        if (! ext4_inode_can_truncate(fs->superblock, inode_ref->inode)) {
     405                // Unable to truncate
     406                return EINVAL;
     407        }
     408
     409        old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
     410
     411        if (old_size == new_size) {
     412                // Nothing to do
     413                return EOK;
     414        }
     415
     416        uint32_t block_size;
     417        uint32_t blocks_count, total_blocks;
     418        uint32_t i;
     419
     420        block_size  = ext4_superblock_get_block_size(fs->superblock);
     421
     422        if (old_size < new_size) {
     423                // Currently not supported to expand the file
     424                // TODO
     425                EXT4FS_DBG("trying to expand the file");
     426                return EINVAL;
     427        }
     428
     429        size_diff = old_size - new_size;
     430        blocks_count = size_diff / block_size;
     431        if (size_diff % block_size != 0) {
     432                blocks_count++;
     433        }
     434
     435        total_blocks = old_size / block_size;
     436        if (old_size % block_size != 0) {
     437                total_blocks++;
     438        }
     439
     440        // starting from 1 because of logical blocks are numbered from 0
     441        for (i = 1; i <= blocks_count; ++i) {
     442                // TODO check retval
     443                // TODO decrement inode->blocks_count
     444
     445                ext4_filesystem_release_inode_block(fs, inode_ref, total_blocks - i);
     446        }
     447
     448        ext4_inode_set_size(inode_ref->inode, new_size);
     449
     450        inode_ref->dirty = true;
     451
     452        return EOK;
     453}
     454
    285455int ext4_filesystem_get_inode_data_block_index(ext4_filesystem_t *fs, ext4_inode_t* inode,
    286456    aoff64_t iblock, uint32_t* fblock)
  • uspace/lib/ext4/libext4_filesystem.h

    rbf66ef4 r3d4fd2c  
    6161                ext4_inode_ref_t **);
    6262extern int ext4_filesystem_put_inode_ref(ext4_inode_ref_t *);
     63extern int ext4_filesystem_free_inode(ext4_filesystem_t *, ext4_inode_ref_t *);
     64extern int ext4_filesystem_truncate_inode(ext4_filesystem_t *,
     65                ext4_inode_ref_t *, aoff64_t);
    6366extern int ext4_filesystem_get_inode_data_block_index(ext4_filesystem_t *,
    6467        ext4_inode_t *, aoff64_t iblock, uint32_t *);
  • uspace/lib/ext4/libext4_ialloc.c

    rbf66ef4 r3d4fd2c  
    3636 */
    3737
     38#include <errno.h>
    3839#include "libext4.h"
     40
     41static uint32_t ext4_ialloc_inode2index_in_group(ext4_superblock_t *sb,
     42                uint32_t inode)
     43{
     44        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
     45        return (inode - 1) % inodes_per_group;
     46}
     47
     48static uint32_t ext4_ialloc_get_bgid_of_inode(ext4_superblock_t *sb,
     49                uint32_t inode)
     50{
     51        uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
     52        return (inode - 1) / inodes_per_group;
     53
     54}
     55
     56
     57int ext4_ialloc_free_inode(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref)
     58{
     59        int rc;
     60        uint32_t block_group = ext4_ialloc_get_bgid_of_inode(
     61                        fs->superblock, inode_ref->index);
     62        uint32_t index_in_group = ext4_ialloc_inode2index_in_group(
     63                        fs->superblock, inode_ref->index);
     64
     65        ext4_block_group_ref_t *bg_ref;
     66        rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
     67        if (rc != EOK) {
     68                EXT4FS_DBG("error in loading bg_ref \%d", rc);
     69                return rc;
     70        }
     71
     72        uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
     73                        bg_ref->block_group, fs->superblock);
     74        block_t *bitmap_block;
     75        rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
     76        if (rc != EOK) {
     77                EXT4FS_DBG("error in loading bitmap \%d", rc);
     78                return rc;
     79        }
     80
     81        ext4_bitmap_free_bit(bitmap_block->data, index_in_group);
     82        bitmap_block->dirty = true;
     83
     84        rc = block_put(bitmap_block);
     85        if (rc != EOK) {
     86                // Error in saving bitmap
     87                ext4_filesystem_put_block_group_ref(bg_ref);
     88                EXT4FS_DBG("error in saving bitmap \%d", rc);
     89                return rc;
     90        }
     91
     92        // Update superblock free inodes count
     93        uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(fs->superblock);
     94        sb_free_inodes--;
     95        ext4_superblock_set_free_inodes_count(fs->superblock, sb_free_inodes);
     96
     97        // Update block group free inodes count
     98        uint32_t free_inodes = ext4_block_group_get_free_inodes_count(
     99                        bg_ref->block_group, fs->superblock);
     100        free_inodes++;
     101        ext4_block_group_set_free_inodes_count(bg_ref->block_group,
     102                        fs->superblock, free_inodes);
     103        bg_ref->dirty = true;
     104
     105        rc = ext4_filesystem_put_block_group_ref(bg_ref);
     106        if (rc != EOK) {
     107                EXT4FS_DBG("error in saving bg_ref \%d", rc);
     108                // TODO error
     109                return rc;
     110        }
     111
     112        return EOK;
     113}
    39114
    40115
  • uspace/lib/ext4/libext4_ialloc.h

    rbf66ef4 r3d4fd2c  
    3434#define LIBEXT4_LIBEXT4_IALLOC_H_
    3535
     36#include "libext4_filesystem.h"
     37#include "libext4_inode.h"
     38
     39extern int ext4_ialloc_free_inode(ext4_filesystem_t *, ext4_inode_ref_t *);
    3640
    3741#endif
Note: See TracChangeset for help on using the changeset viewer.