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

Changeset c4f318d6 in mainline


Ignore:
Timestamp:
2012-02-25T21:24:08Z (8 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
master
Children:
a61ddcf4
Parents:
89a30bd
Message:

some fixes in splitting data blocks (dx_add_entry), not debugged completely

Location:
uspace/lib/ext4
Files:
3 edited

Legend:

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

    r89a30bd rc4f318d6  
    261261
    262262int ext4_directory_append_block(ext4_filesystem_t *fs,
    263                 ext4_inode_ref_t *inode_ref, uint32_t *fblock)
     263                ext4_inode_ref_t *inode_ref, uint32_t *fblock, uint32_t *iblock)
    264264{
    265265        int rc;
     
    288288
    289289        *fblock = phys_block;
     290        *iblock = new_block_idx;
    290291        return EOK;
    291292}
     
    411412
    412413        uint32_t fblock;
    413         rc = ext4_directory_append_block(fs, parent, &fblock);
     414        uint32_t iblock;
     415        rc = ext4_directory_append_block(fs, parent, &fblock, &iblock);
    414416        if (rc != EOK) {
    415417                return rc;
  • uspace/lib/ext4/libext4_directory.h

    r89a30bd rc4f318d6  
    9494
    9595extern int ext4_directory_append_block(ext4_filesystem_t *,
    96                 ext4_inode_ref_t *, uint32_t *);
     96                ext4_inode_ref_t *, uint32_t *, uint32_t *);
    9797
    9898extern void ext4_directory_write_entry(ext4_superblock_t *,
  • uspace/lib/ext4/libext4_directory_index.c

    r89a30bd rc4f318d6  
    456456        uint32_t hash;
    457457        uint32_t rec_len;
    458         ext4_directory_entry_ll_t *dentry;
     458        void *dentry;
    459459} ext4_dx_sort_entry_t;
    460460
     
    491491        memcpy(entry_buffer, old_data_block->data, block_size);
    492492
    493         ext4_directory_dx_countlimit_t *countlimit =
    494                         (ext4_directory_dx_countlimit_t *)index_block->entries;
    495         uint32_t entry_count = ext4_directory_dx_countlimit_get_count(countlimit);
    496         ext4_dx_sort_entry_t *sort_array = malloc(entry_count);
     493        // dot entry has the smalest size available
     494        uint32_t entry_count =  block_size / sizeof(ext4_directory_dx_dot_entry_t);
     495
     496        ext4_dx_sort_entry_t *sort_array = malloc(entry_count * sizeof(ext4_dx_sort_entry_t));
    497497        if (sort_array == NULL) {
    498498                free(entry_buffer);
     
    500500        }
    501501
     502        EXT4FS_DBG("sort_array allocated addr = \%u, size = \%u", (uint32_t)sort_array, entry_count * sizeof(ext4_dx_sort_entry_t));
     503
    502504        ext4_directory_entry_ll_t *dentry = old_data_block->data;
     505
     506        // TODO tady nekde je chyba
     507
     508        EXT4FS_DBG("entry_buffer = \%u", (uint32_t)entry_buffer);
    503509
    504510        int idx = 0;
     
    507513        while ((void *)dentry < old_data_block->data + block_size) {
    508514                char *name = (char *)dentry->name;
     515
    509516                uint8_t len = ext4_directory_entry_ll_get_name_length(fs->superblock, dentry);
    510517                uint32_t hash = ext4_hash_string(hinfo, len, name);
     
    532539
    533540        uint32_t new_fblock;
    534         rc = ext4_directory_append_block(fs, inode_ref, &new_fblock);
     541        uint32_t new_iblock;
     542        rc = ext4_directory_append_block(fs, inode_ref, &new_fblock, &new_iblock);
    535543        if (rc != EOK) {
    536544                free(sort_array);
     
    538546                return rc;
    539547        }
     548
     549        EXT4FS_DBG("new block appended (iblock = \%u)", new_iblock);
    540550
    541551        // Load new block
     
    603613        free(entry_buffer);
    604614
    605         // TODO add new entry to index block
     615        ext4_directory_dx_countlimit_t *countlimit =
     616                        (ext4_directory_dx_countlimit_t *)index_block->entries;
     617        uint32_t count = ext4_directory_dx_countlimit_get_count(countlimit);
     618        count++;
     619        ext4_directory_dx_countlimit_set_count(countlimit, count);
     620
    606621        index_block->position++;
    607622
    608         ext4_directory_dx_entry_set_block(index_block->position, new_fblock);
     623        ext4_directory_dx_entry_set_block(index_block->position, new_iblock);
    609624        ext4_directory_dx_entry_set_hash(index_block->position, new_hash);
    610625
     
    682697                        ext4_directory_write_entry(fs->superblock, de, de_rec_len,
    683698                                child, name, name_size);
     699
     700                                // TODO cleanup
    684701                                target_block->dirty = true;
    685702                                rc = block_put(target_block);
     
    702719                        if (free_space >= required_len) {
    703720
    704                                 EXT4FS_DBG("rec_len = \%u, used_space = \%u, free space = \%u", de_rec_len, used_space, free_space);
    705 
    706721                                // Cut tail of current entry
    707722                                ext4_directory_entry_ll_set_entry_length(de, used_space);
     
    709724                                ext4_directory_write_entry(fs->superblock, new_entry,
    710725                                        free_space, child, name, name_size);
     726
     727                                // TODO cleanup
    711728                                target_block->dirty = true;
    712729                                rc = block_put(target_block);
     
    729746        uint16_t leaf_count = ext4_directory_dx_countlimit_get_count((ext4_directory_dx_countlimit_t *)entries);
    730747
    731         ext4_directory_dx_entry_t *root_entries = ((ext4_directory_dx_node_t *) dx_blocks[0].block->data)->entries;
     748//      ext4_directory_dx_entry_t *root_entries = ((ext4_directory_dx_node_t *) dx_blocks[0].block->data)->entries;
    732749
    733750        if (leaf_limit == leaf_count) {
    734751                EXT4FS_DBG("need to split index block !!!");
    735752
    736                 unsigned int levels = dx_block - dx_blocks;
    737 
    738                 uint16_t root_limit = ext4_directory_dx_countlimit_get_limit((ext4_directory_dx_countlimit_t *)root_entries);
    739                 uint16_t root_count = ext4_directory_dx_countlimit_get_count((ext4_directory_dx_countlimit_t *)root_entries);
    740 
    741                 if ((levels > 0) && (root_limit == root_count)) {
    742                         EXT4FS_DBG("Directory index is full");
    743 
    744                         // ENOSPC - cleanup !!!
    745                         return ENOSPC;
    746                 }
    747 
    748                 uint32_t fblock;
    749                 rc =  ext4_directory_append_block(fs, parent, &fblock);
    750                 if (rc != EOK) {
    751                         // TODO error
    752                 }
    753 
    754                 // New block allocated
    755                 block_t * new_block;
    756                 rc = block_get(&new_block, fs->device, fblock, BLOCK_FLAGS_NOREAD);
    757                 if (rc != EOK) {
    758                         // TODO error
    759                 }
    760 
    761                 memset(new_block->data, 0, block_size);
    762 
    763                 if (levels > 0) {
    764                         EXT4FS_DBG("split index");
    765                 } else {
    766                         EXT4FS_DBG("create second level");
    767                 }
    768         }
    769 
    770         block_t *new_block;
     753//              unsigned int levels = dx_block - dx_blocks;
     754//
     755//              uint16_t root_limit = ext4_directory_dx_countlimit_get_limit((ext4_directory_dx_countlimit_t *)root_entries);
     756//              uint16_t root_count = ext4_directory_dx_countlimit_get_count((ext4_directory_dx_countlimit_t *)root_entries);
     757//
     758//              if ((levels > 0) && (root_limit == root_count)) {
     759//                      EXT4FS_DBG("Directory index is full");
     760//
     761//                      // ENOSPC - cleanup !!!
     762//                      return ENOSPC;
     763//              }
     764//
     765//              uint32_t fblock;
     766//              rc =  ext4_directory_append_block(fs, parent, &fblock);
     767//              if (rc != EOK) {
     768//                      // TODO error
     769//              }
     770//
     771//              // New block allocated
     772//              block_t * new_block;
     773//              rc = block_get(&new_block, fs->device, fblock, BLOCK_FLAGS_NOREAD);
     774//              if (rc != EOK) {
     775//                      // TODO error
     776//              }
     777//
     778//              memset(new_block->data, 0, block_size);
     779//
     780//              if (levels > 0) {
     781//                      EXT4FS_DBG("split index");
     782//              } else {
     783//                      EXT4FS_DBG("create second level");
     784//              }
     785        }
     786
     787        block_t *new_block = NULL;
    771788        rc = ext4_directory_dx_split_data(fs, parent, &hinfo, target_block, dx_block, &new_block);
    772789        if (rc != EOK) {
     
    775792
    776793        // TODO Where to save new entry
    777 
    778 
    779         // TODO
     794        // Position in dx_block is set to NEW block entry
     795        uint32_t new_block_hash = ext4_directory_dx_entry_get_hash(dx_block->position);
     796        if (hinfo.hash >= new_block_hash) {
     797                de = new_block->data;
     798                stop = new_block->data + block_size;
     799        } else {
     800                de = target_block->data;
     801                stop = target_block->data + block_size;
     802        }
     803
     804        while (de < stop) {
     805
     806                uint32_t de_inode = ext4_directory_entry_ll_get_inode(de);
     807                uint16_t de_rec_len = ext4_directory_entry_ll_get_entry_length(de);
     808
     809                if ((de_inode == 0) && (de_rec_len >= required_len)) {
     810                        ext4_directory_write_entry(fs->superblock, de, de_rec_len,
     811                                child, name, name_size);
     812                                goto success;
     813                }
     814
     815                if (de_inode != 0) {
     816                        uint16_t used_name_len = ext4_directory_entry_ll_get_name_length(
     817                                        fs->superblock, de);
     818
     819                        uint16_t used_space = 8 + used_name_len;
     820                        if ((used_name_len % 4) != 0) {
     821                                used_space += 4 - (used_name_len % 4);
     822                        }
     823                        uint16_t free_space = de_rec_len - used_space;
     824
     825                        if (free_space >= required_len) {
     826
     827                                EXT4FS_DBG("rec_len = \%u, used_space = \%u, free space = \%u", de_rec_len, used_space, free_space);
     828
     829                                // Cut tail of current entry
     830                                ext4_directory_entry_ll_set_entry_length(de, used_space);
     831                                ext4_directory_entry_ll_t *new_entry = (void *)de + used_space;
     832                                ext4_directory_write_entry(fs->superblock, new_entry,
     833                                        free_space, child, name, name_size);
     834
     835                                goto success;
     836                        }
     837
     838                }
     839
     840                de = (void *)de + de_rec_len;
     841        }
     842
     843success:
     844
     845        block_put(target_block);
     846        block_put(new_block);
     847
     848        ext4_directory_dx_block_t *dx_it = dx_blocks;
     849
     850        while (dx_it <= dx_block) {
     851                block_put(dx_it->block);
     852                dx_it++;
     853        }
     854
    780855        return EOK;
    781 
    782856}
    783857
Note: See TracChangeset for help on using the changeset viewer.