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

Changeset f577058 in mainline


Ignore:
Timestamp:
2012-02-20T18:31:09Z (10 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master
Children:
ac92b85
Parents:
476bf2f6
Message:

added (not complete) mechanism for splitting data block in directory index

File:
1 edited

Legend:

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

    r476bf2f6 rf577058  
    3838#include <byteorder.h>
    3939#include <errno.h>
     40#include <malloc.h>
     41#include <sort.h>
    4042#include <string.h>
    4143#include "libext4.h"
     
    450452        return ENOENT;
    451453}
     454
     455typedef struct ext4_dx_sort_entry {
     456        uint32_t hash;
     457        ext4_directory_entry_ll_t *dentry;
     458} ext4_dx_sort_entry_t;
     459
     460static int dx_entry_comparator(void *arg1, void *arg2, void *dummy)
     461{
     462        ext4_dx_sort_entry_t *entry1 = arg1;
     463        ext4_dx_sort_entry_t *entry2 = arg2;
     464
     465        if (entry1->hash == entry2->hash) {
     466                return 0;
     467        }
     468
     469        if (entry1->hash < entry2->hash) {
     470                return -1;
     471        } else {
     472                return 1;
     473        }
     474
     475}
     476
     477static int ext4_directory_dx_split_data(ext4_filesystem_t *fs,
     478                ext4_inode_ref_t *inode_ref, ext4_hash_info_t *hinfo,
     479                block_t *data_block, ext4_directory_dx_block_t *index_block)
     480{
     481        int rc;
     482
     483        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
     484        void *entry_buffer = malloc(block_size);
     485        if (entry_buffer == NULL) {
     486                return ENOMEM;
     487        }
     488
     489        // Copy data to buffer
     490        memcpy(entry_buffer, index_block->block->data, block_size);
     491
     492        ext4_directory_dx_countlimit_t *countlimit =
     493                        (ext4_directory_dx_countlimit_t *)index_block->entries;
     494        uint32_t entry_count = ext4_directory_dx_countlimit_get_count(countlimit);
     495        ext4_dx_sort_entry_t *sort_array = malloc(entry_count);
     496        if (sort_array == NULL) {
     497                free(entry_buffer);
     498                return ENOMEM;
     499        }
     500
     501        ext4_directory_entry_ll_t *dentry = data_block->data;
     502
     503        int idx = 0;
     504        while ((void *)dentry < data_block->data + block_size) {
     505                char *name = (char *)dentry->name;
     506                uint8_t len = ext4_directory_entry_ll_get_name_length(fs->superblock, dentry);
     507                uint32_t hash = ext4_hash_string(hinfo, len, name);
     508
     509                sort_array[idx].dentry = dentry;
     510                sort_array[idx].hash = hash;
     511
     512                idx++;
     513                dentry = (void *)dentry + ext4_directory_entry_ll_get_entry_length(dentry);
     514        }
     515
     516        qsort(sort_array, entry_count, sizeof(ext4_dx_sort_entry_t), dx_entry_comparator, NULL);
     517
     518        // TODO split to two groups (by size, NOT by count)
     519
     520        uint32_t new_fblock;
     521        rc = ext4_directory_append_block(fs, inode_ref, &new_fblock);
     522        if (rc != EOK) {
     523                free(sort_array);
     524                free(entry_buffer);
     525                return rc;
     526        }
     527
     528        // TODO load new_block
     529
     530        // TODO write splitted entries to two blocks
     531
     532        // TODO add new entry to index block
     533
     534        return EOK;
     535}
     536
    452537
    453538int ext4_directory_dx_add_entry(ext4_filesystem_t *fs,
     
    602687        }
    603688
     689        rc = ext4_directory_dx_split_data(fs, parent, &hinfo, target, dx_block);
     690        if (rc != EOK) {
     691                // TODO error
     692        }
     693
     694
    604695        // TODO
    605696        return EOK;
Note: See TracChangeset for help on using the changeset viewer.