Changeset 3d4fd2c in mainline for uspace/lib/ext4/libext4_filesystem.c


Ignore:
Timestamp:
2011-11-22T16:56:09Z (12 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)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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)
Note: See TracChangeset for help on using the changeset viewer.