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

Changeset 565b6ff in mainline


Ignore:
Timestamp:
2012-02-05T12:35:02Z (8 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
master
Children:
50601ef
Parents:
512a7df
Message:
  • bugfix in adding directory entry (linear)
  • added skeleton for using directory index (not used yet)
Location:
uspace/lib/ext4
Files:
3 edited

Legend:

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

    r512a7df r565b6ff  
    278278}
    279279
    280 int ext4_directory_add_entry(ext4_filesystem_t *fs, ext4_inode_ref_t * inode_ref,
     280int ext4_directory_add_entry(ext4_filesystem_t *fs, ext4_inode_ref_t * parent,
    281281                const char *entry_name, ext4_inode_ref_t *child)
    282282{
    283283        int rc;
    284284
    285         // USE index if allowed
     285        EXT4FS_DBG("adding entry to directory \%u [ino = \%u, name = \%s]", parent->index, child->index, entry_name);
    286286
    287287        uint16_t name_len = strlen(entry_name);
     288
     289        // Index adding (if allowed)
     290        if (ext4_superblock_has_feature_compatible(fs->superblock, EXT4_FEATURE_COMPAT_DIR_INDEX) &&
     291                        ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX)) {
     292
     293                EXT4FS_DBG("trying INDEX");
     294
     295                rc = ext4_directory_dx_add_entry(fs, parent, name_len, entry_name);
     296
     297                // Check if index is not corrupted
     298                if (rc != EXT4_ERR_BAD_DX_DIR) {
     299
     300                        if (rc != EOK) {
     301                                return rc;
     302                        }
     303
     304                        return EOK;
     305                }
     306
     307                // Needed to clear dir index flag
     308                ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
     309                parent->dirty = true;
     310
     311                EXT4FS_DBG("index is corrupted - doing linear algorithm, index flag cleared");
     312        }
     313
     314        // Linear algorithm
    288315        uint16_t required_len = 8 + name_len + (4 - name_len % 4);
    289316
    290317        ext4_directory_iterator_t it;
    291         rc = ext4_directory_iterator_init(&it, fs, inode_ref, 0);
     318        rc = ext4_directory_iterator_init(&it, fs, parent, 0);
    292319        if (rc != EOK) {
    293320                return rc;
    294321        }
     322
     323        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    295324
    296325        while (it.current != NULL) {
     
    310339                        uint16_t used_name_len = ext4_directory_entry_ll_get_name_length(
    311340                                        fs->superblock, it.current);
    312                         uint16_t free_space = rec_len - 8 - (used_name_len + (4- used_name_len % 4));
     341
     342                        uint16_t used_space = 8 + used_name_len;
     343                        if ((used_name_len % 4) != 0) {
     344                                used_space += 4 - (used_name_len % 4);
     345                        }
     346                        uint16_t free_space = rec_len - used_space;
     347
     348                        EXT4FS_DBG("rec_len = \%u, used_space = \%u, free space = \%u", rec_len, used_space, free_space);
    313349
    314350                        if (free_space >= required_len) {
     
    319355
    320356                                // SEEK manually
    321                                 it.current_offset += used_len;
    322                                 ext4_directory_entry_ll_t *new_entry = it.current_block->data + it.current_offset;
     357                                uint32_t local_offset = (it.current_offset % block_size);
     358                                local_offset += used_len;
     359                                ext4_directory_entry_ll_t *new_entry = it.current_block->data + local_offset;
    323360
    324361                                // We are sure, that both entries are in the same data block
     
    344381
    345382        // Compute next block index and allocate data block
    346         uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
    347383        uint32_t block_idx = pos / block_size;
    348384
    349385        uint32_t fblock;
    350         rc = ext4_filesystem_get_inode_data_block_index(fs, inode_ref->inode, block_idx, &fblock);
     386        rc = ext4_filesystem_get_inode_data_block_index(fs, parent->inode, block_idx, &fblock);
    351387        if (rc != EOK) {
    352388                return rc;
     
    354390
    355391        if (fblock == 0) {
    356                 rc =  ext4_balloc_alloc_block(fs, inode_ref, &fblock);
    357                 if (rc != EOK) {
    358                         return rc;
    359                 }
    360 
    361                 rc = ext4_filesystem_set_inode_data_block_index(fs, inode_ref, block_idx, fblock);
    362                 if (rc != EOK) {
    363                         ext4_balloc_free_block(fs, inode_ref, fblock);
    364                         return rc;
    365                 }
    366 
    367                 uint64_t inode_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
     392                rc =  ext4_balloc_alloc_block(fs, parent, &fblock);
     393                if (rc != EOK) {
     394                        return rc;
     395                }
     396
     397                rc = ext4_filesystem_set_inode_data_block_index(fs, parent, block_idx, fblock);
     398                if (rc != EOK) {
     399                        ext4_balloc_free_block(fs, parent, fblock);
     400                        return rc;
     401                }
     402
     403                uint64_t inode_size = ext4_inode_get_size(fs->superblock, parent->inode);
    368404                inode_size += block_size;
    369                 ext4_inode_set_size(inode_ref->inode, inode_size);
    370 
    371                 inode_ref->dirty = true;
     405                ext4_inode_set_size(parent->inode, inode_size);
     406
     407                parent->dirty = true;
    372408        }
    373409
     
    418454
    419455                EXT4FS_DBG("index is corrupted - doing linear search");
     456
     457                // TODO Needed to clear dir index flag
     458                //ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
     459                //parent->dirty = true;
     460
    420461        }
    421462
  • uspace/lib/ext4/libext4_directory_index.c

    r512a7df r565b6ff  
    391391        }
    392392
     393        // Hardcoded number 2 means maximum height of index tree !!!
    393394        ext4_directory_dx_block_t dx_blocks[2];
    394395        ext4_directory_dx_block_t *dx_block;
     
    449450}
    450451
     452int ext4_directory_dx_add_entry(ext4_filesystem_t *fs,
     453                ext4_inode_ref_t *parent, size_t name_size, const char *name)
     454{
     455        // TODO delete this command
     456        return EXT4_ERR_BAD_DX_DIR;
     457
     458        EXT4FS_DBG("NOT REACHED");
     459
     460        int rc;
     461
     462        // get direct block 0 (index root)
     463        uint32_t root_block_addr;
     464        rc = ext4_filesystem_get_inode_data_block_index(fs, parent->inode, 0, &root_block_addr);
     465        if (rc != EOK) {
     466                return rc;
     467        }
     468
     469        block_t *root_block;
     470        rc = block_get(&root_block, fs->device, root_block_addr, BLOCK_FLAGS_NONE);
     471        if (rc != EOK) {
     472                return rc;
     473        }
     474
     475        ext4_hash_info_t hinfo;
     476        rc = ext4_directory_hinfo_init(&hinfo, root_block, fs->superblock, name_size, name);
     477        if (rc != EOK) {
     478                block_put(root_block);
     479                return EXT4_ERR_BAD_DX_DIR;
     480        }
     481
     482        // Hardcoded number 2 means maximum height of index tree !!!
     483        ext4_directory_dx_block_t dx_blocks[2];
     484        ext4_directory_dx_block_t *dx_block;
     485        rc = ext4_directory_dx_get_leaf(&hinfo, fs, parent->inode, root_block, &dx_block, dx_blocks);
     486        if (rc != EOK) {
     487                block_put(root_block);
     488                return EXT4_ERR_BAD_DX_DIR;
     489        }
     490
     491        // TODO
     492        /*
     493         * 1) try to write entry
     494         * 2) split leaves if necessary
     495         * 3) return
     496         */
     497
     498
     499}
    451500
    452501
  • uspace/lib/ext4/libext4_directory_index.h

    r512a7df r565b6ff  
    123123extern int ext4_directory_dx_find_entry(ext4_directory_iterator_t *,
    124124                ext4_filesystem_t *, ext4_inode_ref_t *, size_t, const char *);
    125 
     125extern int ext4_directory_dx_add_entry(ext4_filesystem_t *,
     126                ext4_inode_ref_t *, size_t, const char *);
    126127
    127128#endif
Note: See TracChangeset for help on using the changeset viewer.