Changeset 5b0a3946 in mainline for uspace/lib/ext4/libext4_extent.c


Ignore:
Timestamp:
2012-04-04T19:17:05Z (13 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9c2d19d
Parents:
e7ed26be
Message:

developement version of releasing more complex extent tree with nontrivial depth (> 0)

File:
1 edited

Legend:

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

    re7ed26be r5b0a3946  
    326326}
    327327
    328 int ext4_extent_release_block(ext4_inode_ref_t *inode_ref, uint32_t iblock)
     328static int ext4_extent_release(ext4_inode_ref_t *inode_ref, ext4_extent_t* extent)
    329329{
    330330        int rc;
    331331
     332        uint64_t start = ext4_extent_get_start(extent);
     333        uint16_t block_count = ext4_extent_get_block_count(extent);
     334
     335        rc = ext4_balloc_free_blocks(inode_ref, start, block_count);
     336        if (rc != EOK) {
     337                EXT4FS_DBG("ERROR");
     338                return rc;
     339        }
     340
     341        return EOK;
     342}
     343
     344// Recursive release
     345static int ext4_extent_release_branch(ext4_inode_ref_t *inode_ref,
     346                ext4_extent_index_t *index)
     347{
     348        int rc;
     349
     350        block_t* block;
     351
     352        uint32_t fblock = ext4_extent_index_get_leaf(index);
     353
     354        EXT4FS_DBG("fblock = \%u", fblock);
     355
     356        rc = block_get(&block, inode_ref->fs->device, fblock, BLOCK_FLAGS_NOREAD);
     357        if (rc != EOK) {
     358                EXT4FS_DBG("ERROR get_block");
     359                return rc;
     360        }
     361
     362        ext4_extent_header_t *header = block->data;
     363
     364        if (ext4_extent_header_get_depth(header)) {
     365
     366                ext4_extent_index_t *idx = EXT4_EXTENT_FIRST_INDEX(header);
     367
     368                for (uint32_t i = 0; i < ext4_extent_header_get_entries_count(header); ++i, ++idx) {
     369                        rc = ext4_extent_release_branch(inode_ref, idx);
     370                        if (rc != EOK) {
     371                                EXT4FS_DBG("error recursion");
     372                                return rc;
     373                        }
     374                }
     375        } else {
     376                ext4_extent_t *ext = EXT4_EXTENT_FIRST(header);
     377
     378                for (uint32_t i = 0; i < ext4_extent_header_get_entries_count(header); ++i, ++ext) {
     379                        rc = ext4_extent_release(inode_ref, ext);
     380                        if (rc != EOK) {
     381                                EXT4FS_DBG("error recursion");
     382                                return rc;
     383                        }
     384                }
     385        }
     386
     387        rc = block_put(block);
     388        if (rc != EOK) {
     389                EXT4FS_DBG("ERROR put_block");
     390                return rc;
     391        }
     392
     393        ext4_balloc_free_block(inode_ref, fblock);
     394
     395        return EOK;
     396}
     397
     398int ext4_extent_release_blocks_from(ext4_inode_ref_t *inode_ref, uint32_t iblock_from)
     399{
     400        int rc;
     401
     402        // 1) Delete iblock and successors in the same extent
     403
    332404        ext4_extent_path_t *path;
    333         rc = ext4_extent_find_extent(inode_ref, iblock, &path);
     405        rc = ext4_extent_find_extent(inode_ref, iblock_from, &path);
    334406        if (rc != EOK) {
    335407                return rc;
     
    338410        ext4_extent_path_t *path_ptr = path;
    339411        while (path_ptr->depth != 0) {
    340                 EXT4FS_DBG("depth = \%u", path_ptr->depth);
    341412                path_ptr++;
    342413        }
     
    344415        assert(path_ptr->extent != NULL);
    345416
    346         uint32_t fblock;
    347         fblock = ext4_extent_get_start(path_ptr->extent) + iblock;
    348         fblock -= ext4_extent_get_first_block(path_ptr->extent);
     417        uint32_t first_fblock;
     418        first_fblock = ext4_extent_get_start(path_ptr->extent) + iblock_from;
     419        first_fblock -= ext4_extent_get_first_block(path_ptr->extent);
    349420
    350421        uint16_t block_count = ext4_extent_get_block_count(path_ptr->extent);
    351422
    352         assert((ext4_extent_get_first_block(path_ptr->extent) + block_count - 1) == iblock);
    353 
    354         block_count--;
     423        uint16_t delete_count = block_count - first_fblock +
     424                        ext4_extent_get_start(path_ptr->extent);
     425
     426        rc = ext4_balloc_free_blocks(inode_ref, first_fblock, delete_count);
     427
     428        block_count -= delete_count;
    355429        ext4_extent_set_block_count(path_ptr->extent, block_count);
    356430
     
    358432
    359433        bool check_tree = false;
     434
     435        uint16_t old_root_entries = ext4_extent_header_get_entries_count(path->header);
    360436
    361437        if (block_count == 0) {
     
    365441
    366442                // If empty leaf, will be released and the whole tree must be checked
    367                 check_tree = true;
    368         }
    369 
    370         while (check_tree) {
    371 
    372                 if (path_ptr > path) {
    373                         // TODO
    374 
    375                         // zahodit fblock
     443                if (path_ptr != path) {
    376444                        rc = ext4_balloc_free_block(inode_ref, path_ptr->block->pba);
    377445                        if (rc != EOK) {
     
    379447                                // TODO
    380448                        }
     449                        check_tree = true;
     450                }
     451        }
     452
     453        --path_ptr;
     454
     455        while ((path_ptr >= path) && check_tree) {
     456
     457                if (path_ptr > path) {
     458
     459                        EXT4FS_DBG("not root");
     460                        uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
     461                        entries--;
     462                        ext4_extent_header_set_entries_count(path_ptr->header, entries);
     463
     464                        if (entries == 0) {
     465                                rc = ext4_balloc_free_block(inode_ref, path_ptr->block->pba);
     466                                if (rc != EOK) {
     467                                        EXT4FS_DBG("ERROR");
     468                                        // TODO
     469                                }
     470                        } else {
     471                                break;
     472                        }
     473
    381474                } else {
    382                         check_tree = false;
     475                        EXT4FS_DBG("root");
     476
     477                        // TODO tady je BUG asi
     478
     479                        uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
     480                        entries--;
     481                        ext4_extent_header_set_entries_count(path_ptr->header, entries);
     482
     483                        break;
    383484                }
    384485
    385486                path_ptr--;
    386 
    387                 uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
    388                 entries--;
    389                 ext4_extent_header_set_entries_count(path_ptr->header, entries);
    390 
    391                 if (entries > 0) {
    392                         check_tree = false;
    393                 }
    394         }
    395 
    396         rc = ext4_balloc_free_block(inode_ref, fblock);
    397         if (rc != EOK) {
    398                 EXT4FS_DBG("ERROR");
    399                 // TODO handle error
     487        }
     488
     489        ext4_extent_header_t *header = path->header;
     490
     491        // 2) delete or successors first level extents/indexes
     492        if (ext4_extent_header_get_depth(header)) {
     493
     494                ext4_extent_index_t *index = path->index + 1;
     495                ext4_extent_index_t *stop = EXT4_EXTENT_FIRST_INDEX(header) +
     496                                old_root_entries;
     497
     498                if (index < stop) {
     499                        inode_ref->dirty = true;
     500                }
     501
     502                while (index < stop) {
     503                        rc = ext4_extent_release_branch(inode_ref, index);
     504                        if (rc != EOK) {
     505                                EXT4FS_DBG("ERR");
     506                                // TODO error
     507                        }
     508                        ++index;
     509
     510                        uint16_t entries = ext4_extent_header_get_entries_count(header);
     511                        entries--;
     512                        ext4_extent_header_set_entries_count(header, entries);
     513
     514                }
     515
     516        } else {
     517
     518                ext4_extent_t *extent = path->extent + 1;
     519                ext4_extent_t *stop = EXT4_EXTENT_FIRST(header) +
     520                                old_root_entries;
     521
     522                if (extent != stop) {
     523                        inode_ref->dirty = true;
     524                }
     525
     526                while (extent < stop) {
     527                        rc = ext4_extent_release(inode_ref, extent);
     528                        if (rc != EOK) {
     529                                EXT4FS_DBG("ERR");
     530                                // TODO error
     531                        }
     532                        ++extent;
     533
     534                        uint16_t entries = ext4_extent_header_get_entries_count(header);
     535                        entries--;
     536                        ext4_extent_header_set_entries_count(header, entries);
     537                }
    400538        }
    401539
     
    413551        free(path);
    414552
    415 
    416553        return EOK;
    417554}
Note: See TracChangeset for help on using the changeset viewer.