Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 5b0a3946 in mainline


Ignore:
Timestamp:
2012-04-04T19:17:05Z (10 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master
Children:
9c2d19d
Parents:
e7ed26be
Message:

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

Location:
uspace/lib/ext4
Files:
4 edited

Legend:

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

    re7ed26be r5b0a3946  
    163163                        ext4_balloc_get_bgid_of_block(sb, first + count);
    164164
    165         assert(block_group_first == block_group_last);
     165        EXT4FS_DBG("first =\%u (bg \%u), last = \%u (bg \%u)", first,  block_group_first, first + count, block_group_last);
    166166
    167167        ext4_block_group_ref_t *bg_ref;
  • 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}
  • uspace/lib/ext4/libext4_extent.h

    re7ed26be r5b0a3946  
    6262
    6363extern int ext4_extent_find_block(ext4_inode_ref_t *, uint32_t, uint32_t *);
    64 extern int ext4_extent_release_block(ext4_inode_ref_t *, uint32_t);
     64extern int ext4_extent_release_blocks_from(ext4_inode_ref_t *, uint32_t);
    6565
    6666#endif
  • uspace/lib/ext4/libext4_filesystem.c

    re7ed26be r5b0a3946  
    216216
    217217        if (ref->dirty) {
    218                  uint16_t checksum = ext4_filesystem_bg_checksum(
     218                uint16_t checksum = ext4_filesystem_bg_checksum(
    219219                                ref->fs->superblock, ref->index, ref->block_group);
    220220
    221                  ext4_block_group_set_checksum(ref->block_group, checksum);
     221                ext4_block_group_set_checksum(ref->block_group, checksum);
    222222
    223223                ref->block->dirty = true;
     
    523523        }
    524524
    525         // starting from 1 because of logical blocks are numbered from 0
    526         for (uint32_t i = 1; i <= diff_blocks_count; ++i) {
    527                 rc = ext4_filesystem_release_inode_block(inode_ref, old_blocks_count - i);
    528                 if (rc != EOK) {
    529                         return rc;
     525        if (ext4_superblock_has_feature_incompatible(
     526                        inode_ref->fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
     527                                ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
     528
     529                rc = ext4_extent_release_blocks_from(inode_ref, old_blocks_count - diff_blocks_count);
     530                if (rc != EOK) {
     531                        return rc;
     532                }
     533        } else {
     534                // starting from 1 because of logical blocks are numbered from 0
     535                for (uint32_t i = 1; i <= diff_blocks_count; ++i) {
     536                        rc = ext4_filesystem_release_inode_block(inode_ref, old_blocks_count - i);
     537                        if (rc != EOK) {
     538                                return rc;
     539                        }
    530540                }
    531541        }
     
    783793        ext4_filesystem_t *fs = inode_ref->fs;
    784794
    785         if (ext4_superblock_has_feature_incompatible(fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    786                         ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
    787 
    788                 return ext4_extent_release_block(inode_ref, iblock);
    789         }
     795        // EXTENTS are handled
     796        assert(! (ext4_superblock_has_feature_incompatible(fs->superblock,
     797                        EXT4_FEATURE_INCOMPAT_EXTENTS) &&
     798                        ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)));
    790799
    791800        ext4_inode_t *inode = inode_ref->inode;
Note: See TracChangeset for help on using the changeset viewer.