Changes in / [9e34750:b5085a7] in mainline


Ignore:
Location:
uspace
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/ext2info/ext2info.c

    r9e34750 rb5085a7  
    590590        printf("  Directory contents:\n");
    591591       
    592         rc = ext2_directory_iterator_init(&it, fs, inode_ref);
     592        rc = ext2_directory_iterator_init(&it, fs, inode_ref, 0);
    593593        if (rc != EOK) {
    594594                printf("Failed initializing directory iterator\n");
  • uspace/lib/ext2/libext2_directory.c

    r9e34750 rb5085a7  
    8686 * @param fs pointer to filesystem structure
    8787 * @param inode pointer to inode reference structure
     88 * @param pos position within inode to start at, 0 is the first entry
    8889 * @return EOK on success or negative error code on failure
    8990 */
    9091int ext2_directory_iterator_init(ext2_directory_iterator_t *it,
    91     ext2_filesystem_t *fs, ext2_inode_ref_t *inode_ref)
    92 {
    93         int rc;
    94         uint32_t block_id;
    95         uint32_t block_size;
    96        
     92    ext2_filesystem_t *fs, ext2_inode_ref_t *inode_ref, aoff64_t pos)
     93{       
    9794        it->inode_ref = inode_ref;
    9895        it->fs = fs;
    99        
    100         /* Get the first data block, so we can get the first entry */
    101         rc = ext2_filesystem_get_inode_data_block_index(fs, inode_ref->inode, 0,
    102             &block_id);
    103         if (rc != EOK) {
    104                 return rc;
    105         }
    106        
    107         rc = block_get(&it->current_block, fs->device, block_id, 0);
    108         if (rc != EOK) {
    109                 return rc;
    110         }
    111        
    112         block_size = ext2_superblock_get_block_size(fs->superblock);
    113        
    114         it->current_offset = 0;
    115         return ext2_directory_iterator_set(it, block_size);
     96        it->current = NULL;
     97        it->current_offset = 0;
     98        it->current_block = NULL;
     99       
     100        return ext2_directory_iterator_seek(it, pos);
    116101}
    117102
     
    124109int ext2_directory_iterator_next(ext2_directory_iterator_t *it)
    125110{
     111        uint16_t skip;
     112       
     113        assert(it->current != NULL);
     114       
     115        skip = ext2_directory_entry_ll_get_entry_length(it->current);
     116       
     117        return ext2_directory_iterator_seek(it, it->current_offset + skip);
     118}
     119
     120/**
     121 * Seek the directory iterator to the given byte offset within the inode.
     122 *
     123 * @param it pointer to iterator to initialize
     124 * @return EOK on success or negative error code on failure
     125 */
     126int ext2_directory_iterator_seek(ext2_directory_iterator_t *it, aoff64_t pos)
     127{
    126128        int rc;
    127         uint16_t skip;
     129       
    128130        uint64_t size;
    129131        aoff64_t current_block_idx;
     
    132134        uint32_t block_size;
    133135       
    134         assert(it->current != NULL);
    135        
    136         skip = ext2_directory_entry_ll_get_entry_length(it->current);
    137136        size = ext2_inode_get_size(it->fs->superblock, it->inode_ref->inode);
    138137       
     138        /* The iterator is not valid until we seek to the desired position */
     139        it->current = NULL;
     140       
    139141        /* Are we at the end? */
    140         if (it->current_offset + skip >= size) {
    141                 rc = block_put(it->current_block);
    142                 it->current_block = NULL;
    143                 it->current = NULL;
    144                 if (rc != EOK) {
    145                         return rc;
     142        if (pos >= size) {             
     143                if (it->current_block) {
     144                        rc = block_put(it->current_block);
     145                        it->current_block = NULL;
     146                        if (rc != EOK) {
     147                                return rc;
     148                        }
    146149                }
    147150               
    148                 it->current_offset += skip;
     151                it->current_offset = pos;
    149152                return EOK;
    150153        }
     
    152155        block_size = ext2_superblock_get_block_size(it->fs->superblock);
    153156        current_block_idx = it->current_offset / block_size;
    154         next_block_idx = (it->current_offset + skip) / block_size;
    155        
    156         /* If we are moving accross block boundary,
     157        next_block_idx = pos / block_size;
     158       
     159        /* If we don't have a block or are moving accross block boundary,
    157160         * we need to get another block
    158161         */
    159         if (current_block_idx != next_block_idx) {
    160                 rc = block_put(it->current_block);
    161                 it->current_block = NULL;
    162                 it->current = NULL;
    163                 if (rc != EOK) {
    164                         return rc;
     162        if (it->current_block == NULL || current_block_idx != next_block_idx) {         
     163                if (it->current_block) {
     164                        rc = block_put(it->current_block);
     165                        it->current_block = NULL;
     166                        if (rc != EOK) {
     167                                return rc;
     168                        }
    165169                }
    166170               
     
    179183        }
    180184       
    181         it->current_offset += skip;
     185        it->current_offset = pos;
    182186        return ext2_directory_iterator_set(it, block_size);
    183187}
    184188
     189/** Setup the entry at the current iterator offset.
     190 *
     191 * This function checks the validity of the directory entry,
     192 * before setting the data pointer.
     193 *
     194 * @return EOK on success or error code on failure
     195 */
    185196static int ext2_directory_iterator_set(ext2_directory_iterator_t *it,
    186197    uint32_t block_size)
  • uspace/lib/ext2/libext2_directory.h

    r9e34750 rb5085a7  
    7171
    7272extern int ext2_directory_iterator_init(ext2_directory_iterator_t *,
    73     ext2_filesystem_t *, ext2_inode_ref_t *);
     73    ext2_filesystem_t *, ext2_inode_ref_t *, aoff64_t);
    7474extern int ext2_directory_iterator_next(ext2_directory_iterator_t *);
     75extern int ext2_directory_iterator_seek(ext2_directory_iterator_t *, aoff64_t pos);
    7576extern int ext2_directory_iterator_fini(ext2_directory_iterator_t *);
    7677
  • uspace/srv/fs/ext2fs/ext2fs_ops.c

    r9e34750 rb5085a7  
    240240        }
    241241       
    242         rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref);
     242        rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref, 0);
    243243        if (rc != EOK) {
    244244                return rc;
     
    478478        }
    479479       
    480         rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref);
     480        rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref, 0);
    481481        if (rc != EOK) {
    482482                EXT2FS_DBG("error %u", rc);
     
    818818{
    819819        ext2_directory_iterator_t it;
    820         aoff64_t cur;
     820        aoff64_t next;
    821821        uint8_t *buf;
    822822        size_t name_size;
     
    824824        bool found = false;
    825825       
    826         rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref);
     826        rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref, pos);
    827827        if (rc != EOK) {
    828828                async_answer_0(callid, rc);
     
    831831        }
    832832       
    833         /* Find the index we want to read
    834          * Note that we need to iterate and count as
    835          * the underlying structure is a linked list
    836          * Moreover, we want to skip . and .. entries
     833        /* Find next interesting directory entry.
     834         * We want to skip . and .. entries
    837835         * as these are not used in HelenOS
    838836         */
    839         cur = 0;
    840837        while (it.current != NULL) {
    841838                if (it.current->inode == 0) {
     
    851848                }
    852849               
    853                 /* Is this the dir entry we want to read? */
    854                 if (cur == pos) {
    855                         /* The on-disk entry does not contain \0 at the end
    856                          * end of entry name, so we copy it to new buffer
    857                          * and add the \0 at the end
    858                          */
    859                         buf = malloc(name_size+1);
    860                         if (buf == NULL) {
    861                                 ext2_directory_iterator_fini(&it);
    862                                 async_answer_0(callid, ENOMEM);
    863                                 async_answer_0(rid, ENOMEM);
    864                                 return;
    865                         }
    866                         memcpy(buf, &it.current->name, name_size);
    867                         *(buf+name_size) = 0;
    868                         found = true;
    869                         (void) async_data_read_finalize(callid, buf, name_size+1);
    870                         free(buf);
    871                         break;
    872                 }
    873                 cur++;
     850                /* The on-disk entry does not contain \0 at the end
     851                        * end of entry name, so we copy it to new buffer
     852                        * and add the \0 at the end
     853                        */
     854                buf = malloc(name_size+1);
     855                if (buf == NULL) {
     856                        ext2_directory_iterator_fini(&it);
     857                        async_answer_0(callid, ENOMEM);
     858                        async_answer_0(rid, ENOMEM);
     859                        return;
     860                }
     861                memcpy(buf, &it.current->name, name_size);
     862                *(buf+name_size) = 0;
     863                found = true;
     864                (void) async_data_read_finalize(callid, buf, name_size+1);
     865                free(buf);
     866                break;
    874867               
    875868skip:
     
    883876        }
    884877       
     878        if (found) {
     879                rc = ext2_directory_iterator_next(&it);
     880                if (rc != EOK) {
     881                        async_answer_0(rid, rc);
     882                        return;
     883                }
     884                next = it.current_offset;
     885        }
     886       
    885887        rc = ext2_directory_iterator_fini(&it);
    886888        if (rc != EOK) {
     
    890892       
    891893        if (found) {
    892                 async_answer_1(rid, EOK, 1);
     894                async_answer_1(rid, EOK, next-pos);
    893895        }
    894896        else {
Note: See TracChangeset for help on using the changeset viewer.