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

Changeset 81a7858 in mainline


Ignore:
Timestamp:
2012-05-10T08:47:06Z (9 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
master
Children:
f2eece1
Parents:
bed78cb
Message:

more comments, now missing very small number of comments

Location:
uspace
Files:
4 edited

Legend:

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

    rbed78cb r81a7858  
    3333/**
    3434 * @file        libext4_block_group.c
    35  * @brief       Ext4 block group structure operations
     35 * @brief       Ext4 block group structure operations.
    3636 */
    3737
  • uspace/lib/ext4/libext4_extent.c

    rbed78cb r81a7858  
    933933}
    934934
    935 /** TODO comment
    936  *
     935/** Append data block to the i-node.
     936 *
     937 * This function allocates data block, tries to append it
     938 * to some existing extent or creates new extents.
     939 * It includes possible extent tree modifications (splitting).
     940 *
     941 * @param inode_ref                     i-node to append block to
     942 * @param iblock                        output logical number of newly allocated block
     943 * @param fblock                        output physical block address of newly allocated block
     944 * @return                                      error code
    937945 */
    938946int ext4_extent_append_block(ext4_inode_ref_t *inode_ref,
     
    968976        }
    969977
    970         // Add new extent to the node
     978        // Add new extent to the node if not present
    971979        if (path_ptr->extent == NULL) {
    972980                goto append_extent;
     
    979987        if (block_count < block_limit) {
    980988
     989                // There is space for new block in the extent
     990
    981991                if (block_count == 0) {
     992
     993                        // Existing extent is empty
    982994
    983995                        rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
     
    986998                        }
    987999
     1000                        // Initialize extent
    9881001                        ext4_extent_set_first_block(path_ptr->extent, new_block_idx);
    9891002                        ext4_extent_set_start(path_ptr->extent, phys_block);
    9901003                        ext4_extent_set_block_count(path_ptr->extent, 1);
    9911004
     1005                        // Update i-node
    9921006                        ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
    9931007                        inode_ref->dirty = true;
     
    9981012                } else {
    9991013
     1014                        // Existing extent contains some blocks
     1015
    10001016                        phys_block = ext4_extent_get_start(path_ptr->extent);
    10011017                        phys_block += ext4_extent_get_block_count(path_ptr->extent);
    10021018
     1019                        // Check if the following block is free for allocation
    10031020                        bool free;
    10041021                        rc = ext4_balloc_try_alloc_block(inode_ref, phys_block, &free);
     
    10081025
    10091026                        if (! free) {
    1010                                 // target is not free
     1027                                // target is not free, new block must be appended to new extent
    10111028                                goto append_extent;
    10121029                        }
    10131030
    10141031
     1032                        // Update extent
    10151033                        ext4_extent_set_block_count(path_ptr->extent, block_count + 1);
    10161034
     1035                        // Update i-node
    10171036                        ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
    10181037                        inode_ref->dirty = true;
     
    10241043        }
    10251044
     1045// Append new extent to the tree
    10261046append_extent:
    10271047
    10281048        phys_block = 0;
    1029         // Allocate and insert insert new block
     1049
     1050        // Allocate new data block
    10301051        rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
    10311052        if (rc != EOK) {
     
    10341055        }
    10351056
     1057        // Append extent for new block (includes tree splitting if needed)
    10361058        rc = ext4_extent_append_extent(inode_ref, path, &path_ptr, new_block_idx);
    10371059        if (rc != EOK) {
     
    10401062        }
    10411063
     1064        // Initialize newly created extent
    10421065        ext4_extent_set_block_count(path_ptr->extent, 1);
    10431066        ext4_extent_set_first_block(path_ptr->extent, new_block_idx);
    10441067        ext4_extent_set_start(path_ptr->extent, phys_block);
    10451068
     1069        // Update i-node
    10461070        ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
    10471071        inode_ref->dirty = true;
     
    10491073        path_ptr->block->dirty = true;
    10501074
     1075
    10511076finish:
    1052 
     1077        // Set return values
    10531078        *iblock = new_block_idx;
    10541079        *fblock = phys_block;
  • uspace/lib/ext4/libext4_filesystem.c

    rbed78cb r81a7858  
    186186 * @param fs            filesystem to find block group on
    187187 * @param bgid          index of block group to load
    188  * @oaram ref           output pointer for reference
     188 * @param ref           output pointer for reference
    189189 * @return                      error code
    190190 */
     
    229229}
    230230
    231 /** TODO comment
    232  *
     231/** Compute checksum of block group descriptor.
     232 *
     233 * It uses crc functions from Linux kernel implementation.
     234 *
     235 * @param sb            superblock
     236 * @param bgid          index of block group in the filesystem
     237 * @param bg            block group to compute checksum for
     238 * @return                      checksum value
    233239 */
    234240static uint16_t ext4_filesystem_bg_checksum(ext4_superblock_t *sb, uint32_t bgid,
    235241                            ext4_block_group_t *bg)
    236242{
     243        // If checksum not supported, 0 will be returned
    237244        uint16_t crc = 0;
    238245
     246        // Compute the checksum only if the filesystem supports it
    239247        if (ext4_superblock_has_feature_read_only(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
    240248
     
    244252                uint32_t offset = (uint32_t)(checksum - base);
    245253
     254                // Convert block group index to little endian
    246255                uint32_t le_group = host2uint32_t_le(bgid);
    247256
     257                // Initialization
    248258                crc = crc16(~0, sb->uuid, sizeof(sb->uuid));
     259
     260                // Include index of block group
    249261                crc = crc16(crc, (uint8_t *)&le_group, sizeof(le_group));
     262
     263                // Compute crc from the first part (stop before checksum field)
    250264                crc = crc16(crc, (uint8_t *)bg, offset);
    251265
    252                 offset += sizeof(bg->checksum); /* skip checksum */
    253 
    254                 /* for checksum of struct ext4_group_desc do the rest...*/
     266                // Skip checksum
     267                offset += sizeof(bg->checksum);
     268
     269                // Checksum of the rest of block group descriptor
    255270                if ((ext4_superblock_has_feature_incompatible(sb, EXT4_FEATURE_INCOMPAT_64BIT)) &&
    256271                        offset < ext4_superblock_get_desc_size(sb)) {
     
    368383}
    369384
    370 /** TODO comment
    371  *
     385/** Put reference to i-node.
     386 *
     387 * @param ref           pointer for reference to be put back
     388 * @return                      error code
    372389 */
    373390int ext4_filesystem_put_inode_ref(ext4_inode_ref_t *ref)
     
    375392        int rc;
    376393
     394        // Check if reference modified
    377395        if (ref->dirty) {
     396
     397                // Mark block dirty for writing changes to physical device
    378398                ref->block->dirty = true;
    379399        }
    380400
     401        // Put back block, that contains i-node
    381402        rc = block_put(ref->block);
    382403        free(ref);
     
    385406}
    386407
    387 /** TODO comment
    388  *
     408/** Allocate new i-node in the filesystem.
     409 *
     410 * @param fs                    filesystem to allocated i-node on
     411 * @param inode_ref             output pointer to return reference to allocated i-node
     412 * @param flags                 flags to be set for newly created i-node
     413 * @return                              error code
    389414 */
    390415int ext4_filesystem_alloc_inode(ext4_filesystem_t *fs,
     
    393418        int rc;
    394419
     420        // Check if newly allocated i-node will be a directory
    395421        bool is_dir = false;
    396422        if (flags & L_DIRECTORY) {
     
    398424        }
    399425
    400         // allocate inode
     426        // Allocate inode by allocation algorithm
    401427        uint32_t index;
    402428        rc = ext4_ialloc_alloc_inode(fs, &index, is_dir);
     
    405431        }
    406432
     433        // Load i-node from on-disk i-node table
    407434        rc = ext4_filesystem_get_inode_ref(fs, index, inode_ref);
    408435        if (rc != EOK) {
     
    411438        }
    412439
    413         // init inode
     440        // Initialize i-node
    414441        ext4_inode_t *inode = (*inode_ref)->inode;
    415442
     
    438465        }
    439466
     467        // Initialize extents if needed
    440468        if (ext4_superblock_has_feature_incompatible(
    441469                        fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
     
    461489}
    462490
    463 /** TODO comment
    464  *
     491/** Release i-node and mark it as free.
     492 *
     493 * @param inode_ref                     i-node to be released
     494 * @return                                      error code
    465495 */
    466496int ext4_filesystem_free_inode(ext4_inode_ref_t *inode_ref)
     
    470500        ext4_filesystem_t *fs = inode_ref->fs;
    471501
     502        // For extents must be data block destroyed by other way
    472503        if (ext4_superblock_has_feature_incompatible(
    473504                        fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
     
    478509        }
    479510
    480         // release all indirect (no data) blocks
     511        // Release all indirect (no data) blocks
    481512
    482513        // 1) Single indirect
     
    583614
    584615finish:
     616
     617        // Mark inode dirty for writing to the physical device
    585618        inode_ref->dirty = true;
    586619
    587         // Free inode
     620        // Free inode by allocator
    588621        if (ext4_inode_is_type(fs->superblock, inode_ref->inode,
    589622                        EXT4_INODE_MODE_DIRECTORY)) {
     
    599632}
    600633
    601 /** TODO comment
    602  *
     634/** Truncate i-node data blocks.
     635 *
     636 * @param inode_ref             i-node to be truncated
     637 * @param new_size              new size of inode (must be < current size)
     638 * @return                              error code
    603639 */
    604640int ext4_filesystem_truncate_inode(
     
    609645        ext4_superblock_t *sb = inode_ref->fs->superblock;
    610646
     647        // Check flags, if i-node can be truncated
    611648        if (! ext4_inode_can_truncate(sb, inode_ref->inode)) {
    612                 // Unable to truncate
    613649                return EINVAL;
    614650        }
    615651
     652        // If sizes are equal, nothing has to be done.
    616653        aoff64_t old_size = ext4_inode_get_size(sb, inode_ref->inode);
    617654        if (old_size == new_size) {
    618                 // Nothing to do
    619655                return EOK;
    620656        }
    621657
    622         // It's not suppported to make the larger file
     658        // It's not suppported to make the larger file by truncate operation
    623659        if (old_size < new_size) {
    624660                return EINVAL;
    625661        }
    626662
     663        // Compute how many blocks will be released
    627664        aoff64_t size_diff = old_size - new_size;
    628665        uint32_t block_size  = ext4_superblock_get_block_size(sb);
     
    641678                                ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
    642679
     680                // Extents require special operation
     681
    643682                rc = ext4_extent_release_blocks_from(inode_ref,
    644683                                old_blocks_count - diff_blocks_count);
     
    647686                }
    648687        } else {
    649                 // starting from 1 because of logical blocks are numbered from 0
     688
     689                // Release data blocks from the end of file
     690
     691                // Starting from 1 because of logical blocks are numbered from 0
    650692                for (uint32_t i = 1; i <= diff_blocks_count; ++i) {
    651693                        rc = ext4_filesystem_release_inode_block(inode_ref, old_blocks_count - i);
     
    656698        }
    657699
     700        // Update i-node
    658701        ext4_inode_set_size(inode_ref->inode, new_size);
    659 
    660702        inode_ref->dirty = true;
    661703
     
    663705}
    664706
    665 /** TODO comment
    666  *
     707/** Get physical block address by logical index of the block.
     708 *
     709 * @param inode_ref             i-node to read block address from
     710 * @param iblock                logical index of block
     711 * @param fblock                output pointer for return physical block address
     712 * @return                              error code
    667713 */
    668714int ext4_filesystem_get_inode_data_block_index(ext4_inode_ref_t *inode_ref,
     
    673719        ext4_filesystem_t *fs = inode_ref->fs;
    674720
     721        // For empty file is situation simple
    675722        if (ext4_inode_get_size(fs->superblock, inode_ref->inode) == 0) {
    676723                *fblock = 0;
     
    680727        uint32_t current_block;
    681728
    682         /* Handle inode using extents */
     729        // Handle i-node using extents
    683730        if (ext4_superblock_has_feature_incompatible(fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    684731                        ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
     732
    685733                rc = ext4_extent_find_block(inode_ref, iblock, &current_block);
    686734
     
    696744        ext4_inode_t *inode = inode_ref->inode;
    697745
    698         /* Handle simple case when we are dealing with direct reference */
     746        // Direct block are read directly from array in i-node structure
    699747        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
    700748                current_block = ext4_inode_get_direct_block(inode, (uint32_t)iblock);
    701749                *fblock = current_block;
     750                return EOK;
     751        }
     752
     753        // Determine indirection level of the target block
     754        int level = -1;
     755        for (int i = 1; i < 4; i++) {
     756                if (iblock < fs->inode_block_limits[i]) {
     757                        level = i;
     758                        break;
     759                }
     760        }
     761
     762        if (level == -1) {
     763                return EIO;
     764        }
     765
     766        // Compute offsets for the topmost level
     767        aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1];
     768        current_block = ext4_inode_get_indirect_block(inode, level-1);
     769        uint32_t offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
     770
     771        // Sparse file
     772        if (current_block == 0) {
     773                *fblock = 0;
     774                return EOK;
     775        }
     776
     777        block_t *block;
     778
     779        /* Navigate through other levels, until we find the block number
     780         * or find null reference meaning we are dealing with sparse file
     781         */
     782        while (level > 0) {
     783
     784                // Load indirect block
     785                rc = block_get(&block, fs->device, current_block, 0);
     786                if (rc != EOK) {
     787                        return rc;
     788                }
     789
     790                // Read block address from indirect block
     791                current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]);
     792
     793                // Put back indirect block untouched
     794                rc = block_put(block);
     795                if (rc != EOK) {
     796                        return rc;
     797                }
     798
     799                // Check for sparse file
     800                if (current_block == 0) {
     801                        *fblock = 0;
     802                        return EOK;
     803                }
     804
     805                // Jump to the next level
     806                level -= 1;
     807
     808                // Termination condition - we have address of data block loaded
     809                if (level == 0) {
     810                        break;
     811                }
     812
     813                // Visit the next level
     814                block_offset_in_level %= fs->inode_blocks_per_level[level];
     815                offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
     816        }
     817
     818        *fblock = current_block;
     819
     820        return EOK;
     821}
     822
     823/** TODO comment
     824 *
     825 */
     826int ext4_filesystem_set_inode_data_block_index(ext4_inode_ref_t *inode_ref,
     827                aoff64_t iblock, uint32_t fblock)
     828{
     829        int rc;
     830
     831        ext4_filesystem_t *fs = inode_ref->fs;
     832
     833        /* Handle inode using extents */
     834        if (ext4_superblock_has_feature_compatible(fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
     835                        ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
     836                // not reachable !!!
     837                return ENOTSUP;
     838        }
     839
     840        /* Handle simple case when we are dealing with direct reference */
     841        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
     842                ext4_inode_set_direct_block(inode_ref->inode, (uint32_t)iblock, fblock);
     843                inode_ref->dirty = true;
    702844                return EOK;
    703845        }
     
    716858        }
    717859
     860        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
     861
    718862        /* Compute offsets for the topmost level */
    719863        aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1];
    720         current_block = ext4_inode_get_indirect_block(inode, level-1);
     864        uint32_t current_block = ext4_inode_get_indirect_block(inode_ref->inode, level-1);
    721865        uint32_t offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
    722866
     867        uint32_t new_block_addr;
     868        block_t *block, *new_block;
     869
    723870        if (current_block == 0) {
    724                 *fblock = 0;
    725                 return EOK;
    726         }
    727 
    728         block_t *block;
     871                rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
     872                if (rc != EOK) {
     873                        return rc;
     874                }
     875
     876                ext4_inode_set_indirect_block(inode_ref->inode, level - 1, new_block_addr);
     877
     878                inode_ref->dirty = true;
     879
     880                rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD);
     881                if (rc != EOK) {
     882                        ext4_balloc_free_block(inode_ref, new_block_addr);
     883                        return rc;
     884                }
     885
     886                memset(new_block->data, 0, block_size);
     887                new_block->dirty = true;
     888
     889                rc = block_put(new_block);
     890                if (rc != EOK) {
     891                        return rc;
     892                }
     893
     894                current_block = new_block_addr;
     895        }
    729896
    730897        /* Navigate through other levels, until we find the block number
     
    732899         */
    733900        while (level > 0) {
     901
    734902                rc = block_get(&block, fs->device, current_block, 0);
    735903                if (rc != EOK) {
     
    739907                current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]);
    740908
     909                if ((level > 1) && (current_block == 0)) {
     910                        rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
     911                        if (rc != EOK) {
     912                                block_put(block);
     913                                return rc;
     914                        }
     915
     916                        rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD);
     917                        if (rc != EOK) {
     918                                block_put(block);
     919                                return rc;
     920                        }
     921
     922                        memset(new_block->data, 0, block_size);
     923                        new_block->dirty = true;
     924
     925                        rc = block_put(new_block);
     926                        if (rc != EOK) {
     927                                block_put(block);
     928                                return rc;
     929                        }
     930
     931                        ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(new_block_addr);
     932                        block->dirty = true;
     933                        current_block = new_block_addr;
     934                }
     935
     936                if (level == 1) {
     937                        ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(fblock);
     938                        block->dirty = true;
     939                }
     940
    741941                rc = block_put(block);
    742942                if (rc != EOK) {
    743943                        return rc;
    744                 }
    745 
    746                 if (current_block == 0) {
    747                         /* This is a sparse file */
    748                         *fblock = 0;
    749                         return EOK;
    750944                }
    751945
     
    764958        }
    765959
    766         *fblock = current_block;
    767 
    768960        return EOK;
    769961}
     
    772964 *
    773965 */
    774 int ext4_filesystem_set_inode_data_block_index(ext4_inode_ref_t *inode_ref,
    775                 aoff64_t iblock, uint32_t fblock)
    776 {
    777         int rc;
     966int ext4_filesystem_release_inode_block(
     967                ext4_inode_ref_t *inode_ref, uint32_t iblock)
     968{
     969        int rc;
     970
     971        uint32_t fblock;
    778972
    779973        ext4_filesystem_t *fs = inode_ref->fs;
    780974
    781         /* Handle inode using extents */
    782         if (ext4_superblock_has_feature_compatible(fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    783                         ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
    784                 // not reachable !!!
    785                 return ENOTSUP;
    786         }
     975        // EXTENTS are handled otherwise
     976        assert(! (ext4_superblock_has_feature_incompatible(fs->superblock,
     977                        EXT4_FEATURE_INCOMPAT_EXTENTS) &&
     978                        ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)));
     979
     980        ext4_inode_t *inode = inode_ref->inode;
    787981
    788982        /* Handle simple case when we are dealing with direct reference */
    789983        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
    790                 ext4_inode_set_direct_block(inode_ref->inode, (uint32_t)iblock, fblock);
    791                 inode_ref->dirty = true;
    792                 return EOK;
    793         }
     984                fblock = ext4_inode_get_direct_block(inode, iblock);
     985                // Sparse file
     986                if (fblock == 0) {
     987                        return EOK;
     988                }
     989
     990                ext4_inode_set_direct_block(inode, iblock, 0);
     991                return ext4_balloc_free_block(inode_ref, fblock);
     992        }
     993
    794994
    795995        /* Determine the indirection level needed to get the desired block */
     
    8061006        }
    8071007
    808         uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    809 
    810         /* Compute offsets for the topmost level */
    811         aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1];
    812         uint32_t current_block = ext4_inode_get_indirect_block(inode_ref->inode, level-1);
    813         uint32_t offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
    814 
    815         uint32_t new_block_addr;
    816         block_t *block, *new_block;
    817 
    818         if (current_block == 0) {
    819                 rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
    820                 if (rc != EOK) {
    821                         return rc;
    822                 }
    823 
    824                 ext4_inode_set_indirect_block(inode_ref->inode, level - 1, new_block_addr);
    825 
    826                 inode_ref->dirty = true;
    827 
    828                 rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD);
    829                 if (rc != EOK) {
    830                         ext4_balloc_free_block(inode_ref, new_block_addr);
    831                         return rc;
    832                 }
    833 
    834                 memset(new_block->data, 0, block_size);
    835                 new_block->dirty = true;
    836 
    837                 rc = block_put(new_block);
    838                 if (rc != EOK) {
    839                         return rc;
    840                 }
    841 
    842                 current_block = new_block_addr;
    843         }
    844 
    845         /* Navigate through other levels, until we find the block number
    846          * or find null reference meaning we are dealing with sparse file
    847          */
    848         while (level > 0) {
    849 
    850                 rc = block_get(&block, fs->device, current_block, 0);
    851                 if (rc != EOK) {
    852                         return rc;
    853                 }
    854 
    855                 current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]);
    856 
    857                 if ((level > 1) && (current_block == 0)) {
    858                         rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
    859                         if (rc != EOK) {
    860                                 block_put(block);
    861                                 return rc;
    862                         }
    863 
    864                         rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD);
    865                         if (rc != EOK) {
    866                                 block_put(block);
    867                                 return rc;
    868                         }
    869 
    870                         memset(new_block->data, 0, block_size);
    871                         new_block->dirty = true;
    872 
    873                         rc = block_put(new_block);
    874                         if (rc != EOK) {
    875                                 block_put(block);
    876                                 return rc;
    877                         }
    878 
    879                         ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(new_block_addr);
    880                         block->dirty = true;
    881                         current_block = new_block_addr;
    882                 }
    883 
    884                 if (level == 1) {
    885                         ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(fblock);
    886                         block->dirty = true;
    887                 }
    888 
    889                 rc = block_put(block);
    890                 if (rc != EOK) {
    891                         return rc;
    892                 }
    893 
    894                 level -= 1;
    895 
    896                 /* If we are on the last level, break here as
    897                  * there is no next level to visit
    898                  */
    899                 if (level == 0) {
    900                         break;
    901                 }
    902 
    903                 /* Visit the next level */
    904                 block_offset_in_level %= fs->inode_blocks_per_level[level];
    905                 offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
    906         }
    907 
    908         return EOK;
    909 }
    910 
    911 /** TODO comment
    912  *
    913  */
    914 int ext4_filesystem_release_inode_block(
    915                 ext4_inode_ref_t *inode_ref, uint32_t iblock)
    916 {
    917         int rc;
    918 
    919         uint32_t fblock;
    920 
    921         ext4_filesystem_t *fs = inode_ref->fs;
    922 
    923         // EXTENTS are handled otherwise
    924         assert(! (ext4_superblock_has_feature_incompatible(fs->superblock,
    925                         EXT4_FEATURE_INCOMPAT_EXTENTS) &&
    926                         ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)));
    927 
    928         ext4_inode_t *inode = inode_ref->inode;
    929 
    930         /* Handle simple case when we are dealing with direct reference */
    931         if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
    932                 fblock = ext4_inode_get_direct_block(inode, iblock);
    933                 // Sparse file
    934                 if (fblock == 0) {
    935                         return EOK;
    936                 }
    937 
    938                 ext4_inode_set_direct_block(inode, iblock, 0);
    939                 return ext4_balloc_free_block(inode_ref, fblock);
    940         }
    941 
    942 
    943         /* Determine the indirection level needed to get the desired block */
    944         int level = -1;
    945         for (int i = 1; i < 4; i++) {
    946                 if (iblock < fs->inode_block_limits[i]) {
    947                         level = i;
    948                         break;
    949                 }
    950         }
    951 
    952         if (level == -1) {
    953                 return EIO;
    954         }
    955 
    9561008        /* Compute offsets for the topmost level */
    9571009        aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1];
     
    10061058}
    10071059
    1008 /** TODO comment
    1009  *
     1060/** Append following logical block to the i-node.
     1061 *
     1062 * @param inode_ref                     i-node to append block to
     1063 * @param fblock                        output physical block address of newly allocated block
     1064 * @param iblock                        output logical number of newly allocated block
     1065 * @return                                      error code
    10101066 */
    10111067int ext4_filesystem_append_inode_block(ext4_inode_ref_t *inode_ref,
     
    10311087        uint32_t block_size = ext4_superblock_get_block_size(sb);
    10321088
    1033         // TODO zarovnat inode size a ne assert!!!
    1034         assert(inode_size % block_size == 0);
     1089        // Align size i-node size
     1090        if ((inode_size % block_size) != 0) {
     1091                inode_size += block_size - (inode_size % block_size);
     1092        }
    10351093
    10361094        // Logical blocks are numbered from 0
    10371095        uint32_t new_block_idx = inode_size / block_size;
    10381096
     1097        // Allocate new physical block
    10391098        uint32_t phys_block;
    10401099        rc =  ext4_balloc_alloc_block(inode_ref, &phys_block);
     
    10431102        }
    10441103
     1104        // Add physical block address to the i-node
    10451105        rc = ext4_filesystem_set_inode_data_block_index(inode_ref, new_block_idx, phys_block);
    10461106        if (rc != EOK) {
     
    10491109        }
    10501110
     1111        // Update i-node
    10511112        ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
    1052 
    10531113        inode_ref->dirty = true;
    10541114
    10551115        *fblock = phys_block;
    10561116        *iblock = new_block_idx;
     1117
    10571118        return EOK;
    10581119}
    10591120
    1060 /** TODO comment
    1061  *
     1121/** Add orphaned i-node to the orphans linked list.
     1122 *
     1123 * @param inode_ref             i-node to be added to orphans list
     1124 * @return                              error code
    10621125 */
    10631126int ext4_filesystem_add_orphan(ext4_inode_ref_t *inode_ref)
     
    10651128        uint32_t next_orphan = ext4_superblock_get_last_orphan(
    10661129                        inode_ref->fs->superblock);
     1130
     1131        // Deletion time is used for holding next item of the list
    10671132        ext4_inode_set_deletion_time(inode_ref->inode, next_orphan);
     1133
     1134        // Head of the list is in the superblock
    10681135        ext4_superblock_set_last_orphan(
    10691136                        inode_ref->fs->superblock, inode_ref->index);
     
    10731140}
    10741141
    1075 /** TODO comment
    1076  *
     1142/** Delete orphaned i-node from the orphans linked list.
     1143 *
     1144 * @param inode_ref             i-node to be deleted from the orphans list
     1145 * @return                              error code
    10771146 */
    10781147int ext4_filesystem_delete_orphan(ext4_inode_ref_t *inode_ref)
     
    10801149        int rc;
    10811150
     1151        // Get head of the linked list
    10821152        uint32_t last_orphan = ext4_superblock_get_last_orphan(
    10831153                        inode_ref->fs->superblock);
     
    10861156        uint32_t next_orphan = ext4_inode_get_deletion_time(inode_ref->inode);
    10871157
     1158        // Check if the head is the target
    10881159        if (last_orphan == inode_ref->index) {
    10891160                ext4_superblock_set_last_orphan(inode_ref->fs->superblock, next_orphan);
     
    10981169                return rc;
    10991170        }
     1171
    11001172        next_orphan = ext4_inode_get_deletion_time(current->inode);
    11011173
    1102         bool found;
    1103 
     1174        bool found = false;
     1175
     1176        // Walk thourgh the linked list
    11041177        while (next_orphan != 0) {
     1178
     1179                // Found?
    11051180                if (next_orphan == inode_ref->index) {
    11061181                        next_orphan = ext4_inode_get_deletion_time(inode_ref->inode);
     
    11211196        }
    11221197
    1123         ext4_inode_set_deletion_time(inode_ref->inode, 0);
     1198        if (found) {
     1199                ext4_inode_set_deletion_time(inode_ref->inode, 0);
     1200        }
    11241201
    11251202        rc = ext4_filesystem_put_inode_ref(current);
  • uspace/srv/fs/ext4fs/ext4fs_ops.c

    rbed78cb r81a7858  
    14411441
    14421442/** Close file.
    1443  *'
     1443 *
    14441444 * @param service_id    device identifier
    14451445 * @param index         i-node number
Note: See TracChangeset for help on using the changeset viewer.