Ignore:
Timestamp:
2012-02-18T12:51:36Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a7d6185
Parents:
856a36b
Message:

adding directory entry using index tree (actually without splitting index block)

File:
1 edited

Legend:

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

    r856a36b r5c83612b  
    3838#include <byteorder.h>
    3939#include <errno.h>
     40#include <string.h>
    4041#include "libext4.h"
    4142
     
    451452
    452453int 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 
     454                ext4_inode_ref_t *parent, ext4_inode_ref_t *child,
     455                size_t name_size, const char *name)
     456{
    460457        int rc;
    461458
     
    489486        }
    490487
     488
     489        // Try to insert to existing data block
     490        uint32_t leaf_block_idx = ext4_directory_dx_entry_get_block(dx_block->position);
     491        uint32_t leaf_block_addr;
     492        rc = ext4_filesystem_get_inode_data_block_index(fs, parent->inode, leaf_block_idx, &leaf_block_addr);
     493        if (rc != EOK) {
     494                return EXT4_ERR_BAD_DX_DIR;
     495        }
     496
     497
     498        block_t *target;
     499        rc = block_get(&target, fs->device, leaf_block_addr, BLOCK_FLAGS_NONE);
     500        if (rc != EOK) {
     501                return EXT4_ERR_BAD_DX_DIR;
     502        }
     503
     504        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
     505        uint16_t required_len = 8 + name_size + (4 - name_size % 4);
     506
     507        ext4_directory_entry_ll_t *de = target->data;
     508        ext4_directory_entry_ll_t *stop = target->data + block_size;
     509
     510        EXT4FS_DBG("before while de = \%u, stop = \%u", (uint32_t)de, (uint32_t)stop);
     511
     512        while (de < stop) {
     513
     514                EXT4FS_DBG("before while de = \%u", (uint32_t)de);
     515
     516                uint32_t de_inode = ext4_directory_entry_ll_get_inode(de);
     517                uint16_t de_rec_len = ext4_directory_entry_ll_get_entry_length(de);
     518
     519                if ((de_inode == 0) && (de_rec_len >= required_len)) {
     520                        ext4_directory_write_entry(fs->superblock, de, de_rec_len,
     521                                child, name, name_size);
     522                                target->dirty = true;
     523                                rc = block_put(target);
     524                                if (rc != EOK) {
     525                                        return EXT4_ERR_BAD_DX_DIR;
     526                                }
     527                                return EOK;
     528                }
     529
     530                if (de_inode != 0) {
     531                        uint16_t used_name_len = ext4_directory_entry_ll_get_name_length(
     532                                        fs->superblock, de);
     533
     534                        uint16_t used_space = 8 + used_name_len;
     535                        if ((used_name_len % 4) != 0) {
     536                                used_space += 4 - (used_name_len % 4);
     537                        }
     538                        uint16_t free_space = de_rec_len - used_space;
     539
     540                        if (free_space >= required_len) {
     541
     542                                EXT4FS_DBG("rec_len = \%u, used_space = \%u, free space = \%u", de_rec_len, used_space, free_space);
     543
     544                                // Cut tail of current entry
     545                                ext4_directory_entry_ll_set_entry_length(de, used_space);
     546                                ext4_directory_entry_ll_t *new_entry = (void *)de + used_space;
     547                                ext4_directory_write_entry(fs->superblock, new_entry,
     548                                        free_space, child, name, name_size);
     549                                target->dirty = true;
     550                                rc = block_put(target);
     551                                if (rc != EOK) {
     552                                        return EXT4_ERR_BAD_DX_DIR;
     553                                }
     554                                return EOK;
     555
     556                        }
     557
     558                }
     559
     560                de = (void *)de + de_rec_len;
     561        }
     562
     563
     564        EXT4FS_DBG("ERRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");
     565        return EXT4_ERR_BAD_DX_DIR;
     566
     567        // if ENOSPC in block -> next code
     568
     569        ext4_directory_dx_entry_t *entries = ((ext4_directory_dx_node_t *) dx_block->block->data)->entries;
     570        uint16_t limit = ext4_directory_dx_countlimit_get_limit((ext4_directory_dx_countlimit_t *)entries);
     571        uint16_t count = ext4_directory_dx_countlimit_get_count((ext4_directory_dx_countlimit_t *)entries);
     572
     573        ext4_directory_dx_entry_t *root_entries = ((ext4_directory_dx_node_t *) dx_blocks[0].block->data)->entries;
     574
     575        if (limit == count) {
     576                EXT4FS_DBG("need to split index block !!!");
     577
     578                unsigned int levels = dx_block - dx_blocks;
     579
     580                uint16_t root_limit = ext4_directory_dx_countlimit_get_limit((ext4_directory_dx_countlimit_t *)root_entries);
     581                uint16_t root_count = ext4_directory_dx_countlimit_get_count((ext4_directory_dx_countlimit_t *)root_entries);
     582
     583                if ((levels > 0) && (root_limit == root_count)) {
     584                        EXT4FS_DBG("Directory index is full");
     585
     586                        // ENOSPC - cleanup !!!
     587                        return ENOSPC;
     588                }
     589
     590
     591        }
     592
    491593        // TODO
    492         /*
    493          * 1) try to write entry
    494          * 2) split leaves if necessary
    495          * 3) return
    496          */
    497 
     594        return EOK;
    498595
    499596}
Note: See TracChangeset for help on using the changeset viewer.