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

Changeset 3e2952b in mainline


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

more debugged version of releasing file/dir using extent

Location:
uspace/lib/ext4
Files:
3 edited

Legend:

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

    r9c2d19d r3e2952b  
    161161                        ext4_balloc_get_bgid_of_block(sb, first);
    162162        uint32_t block_group_last =
    163                         ext4_balloc_get_bgid_of_block(sb, first + count);
    164 
    165         EXT4FS_DBG("first =\%u (bg \%u), last = \%u (bg \%u)", first,  block_group_first, first + count, block_group_last);
    166 
    167         ext4_block_group_ref_t *bg_ref;
     163                        ext4_balloc_get_bgid_of_block(sb, first + count - 1);
     164
     165        assert(block_group_first == block_group_last);
     166
    168167        rc = ext4_filesystem_get_block_group_ref(fs, block_group_first, &bg_ref);
    169168        if (rc != EOK) {
  • uspace/lib/ext4/libext4_extent.c

    r9c2d19d r3e2952b  
    400400        int rc;
    401401
    402         // 1) Delete iblock and successors in the same extent
    403 
     402        // Find the first extent to modify
    404403        ext4_extent_path_t *path;
    405404        rc = ext4_extent_find_extent(inode_ref, iblock_from, &path);
     
    408407        }
    409408
     409        // Jump to last item of the path (extent)
    410410        ext4_extent_path_t *path_ptr = path;
    411411        while (path_ptr->depth != 0) {
     
    415415        assert(path_ptr->extent != NULL);
    416416
     417        // First extent maybe released partially
    417418        uint32_t first_fblock;
    418419        first_fblock = ext4_extent_get_start(path_ptr->extent) + iblock_from;
     
    425426
    426427        rc = ext4_balloc_free_blocks(inode_ref, first_fblock, delete_count);
     428        if (rc != EOK) {
     429                // TODO goto cleanup
     430                EXT4FS_DBG("ERROR");
     431                return rc;
     432        }
    427433
    428434        block_count -= delete_count;
    429435        ext4_extent_set_block_count(path_ptr->extent, block_count);
    430436
    431         path_ptr->block->dirty = true;
    432 
    433         bool check_tree = false;
    434 
    435         uint16_t old_root_entries = ext4_extent_header_get_entries_count(path->header);
    436 
     437        uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
     438        ext4_extent_t *tmp_ext = path_ptr->extent + 1;
     439        ext4_extent_t *stop_ext = EXT4_EXTENT_FIRST(path_ptr->header) + entries;
     440
     441        // If first extent empty, release it
    437442        if (block_count == 0) {
    438                 uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
    439443                entries--;
    440444                ext4_extent_header_set_entries_count(path_ptr->header, entries);
    441 
    442                 // If empty leaf, will be released and the whole tree must be checked
    443                 if (path_ptr != path) {
    444                         rc = ext4_balloc_free_block(inode_ref, path_ptr->block->pba);
    445                         if (rc != EOK) {
    446                                 EXT4FS_DBG("ERROR");
    447                                 // TODO
    448                         }
    449                         check_tree = true;
    450                 }
    451         }
    452 
     445        }
     446
     447        // Release all successors of the first extent in the same node
     448        while (tmp_ext < stop_ext) {
     449                first_fblock = ext4_extent_get_start(tmp_ext);
     450                delete_count = ext4_extent_get_block_count(tmp_ext);
     451
     452                rc = ext4_balloc_free_blocks(inode_ref, first_fblock, delete_count);
     453                if (rc != EOK) {
     454                        // TODO goto cleanup
     455                        EXT4FS_DBG("ERROR");
     456                        return rc;
     457                }
     458
     459                entries--;
     460                ext4_extent_header_set_entries_count(path_ptr->header, entries);
     461
     462                tmp_ext++;
     463        }
     464
     465        // If leaf node is empty, the whole tree must be checked and the node will be released
     466        bool check_tree = false;
     467
     468        // Don't release root block (including inode data) !!!
     469        if ((path_ptr != path) && (entries == 0)) {
     470                rc = ext4_balloc_free_block(inode_ref, path_ptr->block->lba);
     471                if (rc != EOK) {
     472                        EXT4FS_DBG("ERROR");
     473                        // TODO goto cleanup
     474                        return rc;
     475                }
     476                check_tree = true;
     477        }
     478
     479        // Jump to the parent
    453480        --path_ptr;
    454481
    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);
     482        // release all successors in all levels
     483        while(path_ptr >= path) {
     484                entries = ext4_extent_header_get_entries_count(path_ptr->header);
     485                ext4_extent_index_t *index = path_ptr->index + 1;
     486                ext4_extent_index_t *stop =
     487                                EXT4_EXTENT_FIRST_INDEX(path_ptr->header) + entries;
     488
     489                if (check_tree) {
    461490                        entries--;
    462491                        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 
    474                 } else {
    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;
    484                 }
    485 
    486                 path_ptr--;
    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;
    500492                }
    501493
     
    504496                        if (rc != EOK) {
    505497                                EXT4FS_DBG("ERR");
    506                                 // TODO error
     498                                // TODO goto cleanup
     499                                return rc;
    507500                        }
    508501                        ++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);
     502                        --entries;
     503                        ext4_extent_header_set_entries_count(path_ptr->header, entries);
     504                }
     505
     506                path_ptr->block->dirty = true;
     507
     508                if ((entries == 0) && (path_ptr != path)) {
     509                        rc = ext4_balloc_free_block(inode_ref, path_ptr->block->lba);
    528510                        if (rc != EOK) {
    529                                 EXT4FS_DBG("ERR");
    530                                 // TODO error
     511                                EXT4FS_DBG("ERROR");
     512                                // TODO goto cleanup
     513                                return rc;
    531514                        }
    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                 }
    538         }
    539 
     515                        check_tree = true;
     516                } else {
     517                        check_tree = false;
     518                }
     519
     520                --path_ptr;
     521        }
     522
     523
     524        // Finish
    540525        uint16_t depth = path->depth;
    541526
  • uspace/lib/ext4/libext4_filesystem.c

    r9c2d19d r3e2952b  
    366366        int rc;
    367367
     368        ext4_filesystem_t *fs = inode_ref->fs;
     369
     370        if (ext4_superblock_has_feature_incompatible(
     371                        fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
     372                                ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
     373
     374                // Data structures are released during truncate operation...
     375                goto finish;
     376        }
     377
    368378        // release all indirect (no data) blocks
    369379
     
    378388                ext4_inode_set_indirect_block(inode_ref->inode, 0, 0);
    379389        }
    380 
    381         ext4_filesystem_t *fs = inode_ref->fs;
    382390
    383391        block_t *block;
     
    472480        }
    473481
     482finish:
    474483        inode_ref->dirty = true;
    475484
Note: See TracChangeset for help on using the changeset viewer.