Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ext4/src/directory.c

    r5a6cc679 ra35b458  
    110110                return ((uint16_t)de->name_length_high) << 8 |
    111111                    ((uint16_t)de->name_length);
    112        
     112
    113113        return de->name_length;
    114114
     
    126126{
    127127        de->name_length = (length << 8) >> 8;
    128        
     128
    129129        if ((ext4_superblock_get_rev_level(sb) == 0) &&
    130130            (ext4_superblock_get_minor_rev_level(sb) < 5))
    131131                de->name_length_high = length >> 8;
    132        
     132
    133133        /* Else do nothing */
    134134}
     
    148148            (ext4_superblock_get_minor_rev_level(sb) >= 5))
    149149                return de->inode_type;
    150        
     150
    151151        return EXT4_DIRECTORY_FILETYPE_UNKNOWN;
    152152}
     
    165165            (ext4_superblock_get_minor_rev_level(sb) >= 5))
    166166                de->inode_type = type;
    167        
     167
    168168        /* Else do nothing */
    169169}
     
    190190        it->current_offset = 0;
    191191        it->current_block = NULL;
    192        
     192
    193193        return ext4_directory_iterator_seek(it, pos);
    194194}
     
    204204{
    205205        assert(it->current != NULL);
    206        
     206
    207207        uint16_t skip = ext4_directory_entry_ll_get_entry_length(it->current);
    208        
     208
    209209        return ext4_directory_iterator_seek(it, it->current_offset + skip);
    210210}
     
    224224        uint64_t size = ext4_inode_get_size(it->inode_ref->fs->superblock,
    225225            it->inode_ref->inode);
    226        
     226
    227227        /* The iterator is not valid until we seek to the desired position */
    228228        it->current = NULL;
    229        
     229
    230230        /* Are we at the end? */
    231231        if (pos >= size) {
     
    233233                        errno_t rc = block_put(it->current_block);
    234234                        it->current_block = NULL;
    235                        
     235
    236236                        if (rc != EOK)
    237237                                return rc;
    238238                }
    239                
     239
    240240                it->current_offset = pos;
    241241                return EOK;
    242242        }
    243        
     243
    244244        /* Compute next block address */
    245245        uint32_t block_size =
     
    247247        aoff64_t current_block_idx = it->current_offset / block_size;
    248248        aoff64_t next_block_idx = pos / block_size;
    249        
     249
    250250        /*
    251251         * If we don't have a block or are moving accross block boundary,
     
    257257                        errno_t rc = block_put(it->current_block);
    258258                        it->current_block = NULL;
    259                        
     259
    260260                        if (rc != EOK)
    261261                                return rc;
    262262                }
    263                
     263
    264264                uint32_t next_block_phys_idx;
    265265                errno_t rc = ext4_filesystem_get_inode_data_block_index(it->inode_ref,
     
    267267                if (rc != EOK)
    268268                        return rc;
    269                
     269
    270270                rc = block_get(&it->current_block, it->inode_ref->fs->device,
    271271                    next_block_phys_idx, BLOCK_FLAGS_NONE);
     
    275275                }
    276276        }
    277        
     277
    278278        it->current_offset = pos;
    279        
     279
    280280        return ext4_directory_iterator_set(it, block_size);
    281281}
     
    293293{
    294294        it->current = NULL;
    295        
     295
    296296        uint32_t offset_in_block = it->current_offset % block_size;
    297        
     297
    298298        /* Ensure proper alignment */
    299299        if ((offset_in_block % 4) != 0)
    300300                return EIO;
    301        
     301
    302302        /* Ensure that the core of the entry does not overflow the block */
    303303        if (offset_in_block > block_size - 8)
    304304                return EIO;
    305        
     305
    306306        ext4_directory_entry_ll_t *entry =
    307307            it->current_block->data + offset_in_block;
    308        
     308
    309309        /* Ensure that the whole entry does not overflow the block */
    310310        uint16_t length = ext4_directory_entry_ll_get_entry_length(entry);
    311311        if (offset_in_block + length > block_size)
    312312                return EIO;
    313        
     313
    314314        /* Ensure the name length is not too large */
    315315        if (ext4_directory_entry_ll_get_name_length(
    316316            it->inode_ref->fs->superblock, entry) > length-8)
    317317                return EIO;
    318        
     318
    319319        /* Everything OK - "publish" the entry */
    320320        it->current = entry;
     
    335335        it->inode_ref = NULL;
    336336        it->current = NULL;
    337        
     337
    338338        if (it->current_block)
    339339                return block_put(it->current_block);
    340        
     340
    341341        return EOK;
    342342}
     
    359359        uint32_t block_size = ext4_superblock_get_block_size(sb);
    360360        assert(entry_len <= block_size);
    361        
     361
    362362        /* Set basic attributes */
    363363        ext4_directory_entry_ll_set_inode(entry, child->index);
    364364        ext4_directory_entry_ll_set_entry_length(entry, entry_len);
    365365        ext4_directory_entry_ll_set_name_length(sb, entry, name_len);
    366        
     366
    367367        /* Write name */
    368368        memcpy(entry->name, name, name_len);
    369        
     369
    370370        /* Set type of entry */
    371371        if (ext4_inode_is_type(sb, child->inode, EXT4_INODE_MODE_DIRECTORY))
     
    390390{
    391391        ext4_filesystem_t *fs = parent->fs;
    392        
     392
    393393        /* Index adding (if allowed) */
    394394        if ((ext4_superblock_has_feature_compatible(fs->superblock,
     
    405405                parent->dirty = true;
    406406        }
    407        
     407
    408408        /* Linear algorithm */
    409        
     409
    410410        uint32_t iblock = 0;
    411411        uint32_t fblock = 0;
     
    413413        uint32_t inode_size = ext4_inode_get_size(fs->superblock, parent->inode);
    414414        uint32_t total_blocks = inode_size / block_size;
    415        
     415
    416416        uint32_t name_len = str_size(name);
    417        
     417
    418418        /* Find block, where is space for new entry and try to add */
    419419        bool success = false;
     
    423423                if (rc != EOK)
    424424                        return rc;
    425                
     425
    426426                block_t *block;
    427427                rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
    428428                if (rc != EOK)
    429429                        return rc;
    430                
     430
    431431                /* If adding is successful, function can finish */
    432432                rc = ext4_directory_try_insert_entry(fs->superblock, block,
     
    434434                if (rc == EOK)
    435435                        success = true;
    436                
     436
    437437                rc = block_put(block);
    438438                if (rc != EOK)
    439439                        return rc;
    440                
     440
    441441                if (success)
    442442                        return EOK;
    443443        }
    444        
     444
    445445        /* No free block found - needed to allocate next data block */
    446        
     446
    447447        iblock = 0;
    448448        fblock = 0;
     
    450450        if (rc != EOK)
    451451                return rc;
    452        
     452
    453453        /* Load new block */
    454454        block_t *new_block;
     
    456456        if (rc != EOK)
    457457                return rc;
    458        
     458
    459459        /* Fill block with zeroes */
    460460        memset(new_block->data, 0, block_size);
     
    462462        ext4_directory_write_entry(fs->superblock, block_entry, block_size,
    463463            child, name, name_len);
    464        
     464
    465465        /* Save new block */
    466466        new_block->dirty = true;
    467467        rc = block_put(new_block);
    468        
     468
    469469        return rc;
    470470}
     
    483483{
    484484        uint32_t name_len = str_size(name);
    485        
     485
    486486        ext4_superblock_t *sb = parent->fs->superblock;
    487        
     487
    488488        /* Index search */
    489489        if ((ext4_superblock_has_feature_compatible(sb,
     
    492492                errno_t rc = ext4_directory_dx_find_entry(result, parent, name_len,
    493493                    name);
    494                
     494
    495495                /* Check if index is not corrupted */
    496496                if (rc != EXT4_ERR_BAD_DX_DIR) {
    497497                        if (rc != EOK)
    498498                                return rc;
    499                        
     499
    500500                        return EOK;
    501501                }
    502                
     502
    503503                /* Needed to clear dir index flag if corrupted */
    504504                ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
    505505                parent->dirty = true;
    506506        }
    507        
     507
    508508        /* Linear algorithm */
    509        
     509
    510510        uint32_t iblock;
    511511        uint32_t fblock;
     
    513513        uint32_t inode_size = ext4_inode_get_size(sb, parent->inode);
    514514        uint32_t total_blocks = inode_size / block_size;
    515        
     515
    516516        /* Walk through all data blocks */
    517517        for (iblock = 0; iblock < total_blocks; ++iblock) {
     
    521521                if (rc != EOK)
    522522                        return rc;
    523                
     523
    524524                /* Load data block */
    525525                block_t *block;
     
    527527                if (rc != EOK)
    528528                        return rc;
    529                
     529
    530530                /* Try to find entry in block */
    531531                ext4_directory_entry_ll_t *res_entry;
     
    537537                        return EOK;
    538538                }
    539                
     539
    540540                /* Entry not found - put block and continue to the next block */
    541                
     541
    542542                rc = block_put(block);
    543543                if (rc != EOK)
    544544                        return rc;
    545545        }
    546        
     546
    547547        /* Entry was not found */
    548        
     548
    549549        result->block = NULL;
    550550        result->dentry =  NULL;
    551        
     551
    552552        return ENOENT;
    553553}
     
    567567            EXT4_INODE_MODE_DIRECTORY))
    568568                return ENOTDIR;
    569        
     569
    570570        /* Try to find entry */
    571571        ext4_directory_search_result_t result;
     
    573573        if (rc != EOK)
    574574                return rc;
    575        
     575
    576576        /* Invalidate entry */
    577577        ext4_directory_entry_ll_set_inode(result.dentry, 0);
    578        
     578
    579579        /* Store entry position in block */
    580580        uint32_t pos = (void *) result.dentry - result.block->data;
    581        
     581
    582582        /*
    583583         * If entry is not the first in block, it must be merged
     
    586586        if (pos != 0) {
    587587                uint32_t offset = 0;
    588                
     588
    589589                /* Start from the first entry in block */
    590590                ext4_directory_entry_ll_t *tmp_dentry = result.block->data;
    591591                uint16_t tmp_dentry_length =
    592592                    ext4_directory_entry_ll_get_entry_length(tmp_dentry);
    593                
     593
    594594                /* Find direct predecessor of removed entry */
    595595                while ((offset + tmp_dentry_length) < pos) {
     
    600600                            ext4_directory_entry_ll_get_entry_length(tmp_dentry);
    601601                }
    602                
     602
    603603                assert(tmp_dentry_length + offset == pos);
    604                
     604
    605605                /* Add to removed entry length to predecessor's length */
    606606                uint16_t del_entry_length =
     
    609609                    tmp_dentry_length + del_entry_length);
    610610        }
    611        
     611
    612612        result.block->dirty = true;
    613        
     613
    614614        return ext4_directory_destroy_result(&result);
    615615}
     
    633633        uint32_t block_size = ext4_superblock_get_block_size(sb);
    634634        uint16_t required_len = sizeof(ext4_fake_directory_entry_t) + name_len;
    635        
     635
    636636        if ((required_len % 4) != 0)
    637637                required_len += 4 - (required_len % 4);
    638        
     638
    639639        /* Initialize pointers, stop means to upper bound */
    640640        ext4_directory_entry_ll_t *dentry = target_block->data;
    641641        ext4_directory_entry_ll_t *stop = target_block->data + block_size;
    642        
     642
    643643        /*
    644644         * Walk through the block and check for invalid entries
     
    648648                uint32_t inode = ext4_directory_entry_ll_get_inode(dentry);
    649649                uint16_t rec_len = ext4_directory_entry_ll_get_entry_length(dentry);
    650                
     650
    651651                /* If invalid and large enough entry, use it */
    652652                if ((inode == 0) && (rec_len >= required_len)) {
     
    654654                            name, name_len);
    655655                        target_block->dirty = true;
    656                        
     656
    657657                        return EOK;
    658658                }
    659                
     659
    660660                /* Valid entry, try to split it */
    661661                if (inode != 0) {
    662662                        uint16_t used_name_len =
    663663                            ext4_directory_entry_ll_get_name_length(sb, dentry);
    664                        
     664
    665665                        uint16_t used_space =
    666666                            sizeof(ext4_fake_directory_entry_t) + used_name_len;
    667                        
     667
    668668                        if ((used_name_len % 4) != 0)
    669669                                used_space += 4 - (used_name_len % 4);
    670                        
     670
    671671                        uint16_t free_space = rec_len - used_space;
    672                        
     672
    673673                        /* There is free space for new entry */
    674674                        if (free_space >= required_len) {
     
    679679                                ext4_directory_write_entry(sb, new_entry,
    680680                                    free_space, child, name, name_len);
    681                                
     681
    682682                                target_block->dirty = true;
    683                                
     683
    684684                                return EOK;
    685685                        }
    686686                }
    687                
     687
    688688                /* Jump to the next entry */
    689689                dentry = (void *) dentry + rec_len;
    690690        }
    691        
     691
    692692        /* No free space found for new entry */
    693693        return ENOSPC;
     
    711711        ext4_directory_entry_ll_t *dentry =
    712712            (ext4_directory_entry_ll_t *) block->data;
    713        
     713
    714714        /* Set upper bound for cycling */
    715715        uint8_t *addr_limit = block->data + ext4_superblock_get_block_size(sb);
    716        
     716
    717717        /* Walk through the block and check entries */
    718718        while ((uint8_t *) dentry < addr_limit) {
     
    720720                if ((uint8_t *) dentry + name_len > addr_limit)
    721721                        break;
    722                
     722
    723723                /* Valid entry - check it */
    724724                if (dentry->inode != 0) {
     
    733733                        }
    734734                }
    735                
     735
    736736                uint16_t dentry_len =
    737737                    ext4_directory_entry_ll_get_entry_length(dentry);
    738                
     738
    739739                /* Corrupted entry */
    740740                if (dentry_len == 0)
    741741                        return EINVAL;
    742                
     742
    743743                /* Jump to next entry */
    744744                dentry = (ext4_directory_entry_ll_t *) ((uint8_t *) dentry + dentry_len);
    745745        }
    746        
     746
    747747        /* Entry not found */
    748748        return ENOENT;
     
    760760        if (result->block)
    761761                return block_put(result->block);
    762        
     762
    763763        return EOK;
    764764}
Note: See TracChangeset for help on using the changeset viewer.