Changeset 4e36219 in mainline
- Timestamp:
- 2011-06-08T19:18:52Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b5085a7, c028b22
- Parents:
- 911ee54
- Location:
- uspace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/ext2info/ext2info.c
r911ee54 r4e36219 590 590 printf(" Directory contents:\n"); 591 591 592 rc = ext2_directory_iterator_init(&it, fs, inode_ref );592 rc = ext2_directory_iterator_init(&it, fs, inode_ref, 0); 593 593 if (rc != EOK) { 594 594 printf("Failed initializing directory iterator\n"); -
uspace/lib/ext2/libext2_directory.c
r911ee54 r4e36219 86 86 * @param fs pointer to filesystem structure 87 87 * @param inode pointer to inode reference structure 88 * @param pos position within inode to start at, 0 is the first entry 88 89 * @return EOK on success or negative error code on failure 89 90 */ 90 91 int 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 { 97 94 it->inode_ref = inode_ref; 98 95 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); 116 101 } 117 102 … … 124 109 int ext2_directory_iterator_next(ext2_directory_iterator_t *it) 125 110 { 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 */ 126 int ext2_directory_iterator_seek(ext2_directory_iterator_t *it, aoff64_t pos) 127 { 126 128 int rc; 127 uint16_t skip;129 128 130 uint64_t size; 129 131 aoff64_t current_block_idx; … … 132 134 uint32_t block_size; 133 135 134 assert(it->current != NULL);135 136 skip = ext2_directory_entry_ll_get_entry_length(it->current);137 136 size = ext2_inode_get_size(it->fs->superblock, it->inode_ref->inode); 138 137 138 /* The iterator is not valid until we seek to the desired position */ 139 it->current = NULL; 140 139 141 /* 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 } 146 149 } 147 150 148 it->current_offset += skip;151 it->current_offset = pos; 149 152 return EOK; 150 153 } … … 152 155 block_size = ext2_superblock_get_block_size(it->fs->superblock); 153 156 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, 157 160 * we need to get another block 158 161 */ 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 } 165 169 } 166 170 … … 179 183 } 180 184 181 it->current_offset += skip;185 it->current_offset = pos; 182 186 return ext2_directory_iterator_set(it, block_size); 183 187 } 184 188 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 */ 185 196 static int ext2_directory_iterator_set(ext2_directory_iterator_t *it, 186 197 uint32_t block_size) -
uspace/lib/ext2/libext2_directory.h
r911ee54 r4e36219 71 71 72 72 extern 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); 74 74 extern int ext2_directory_iterator_next(ext2_directory_iterator_t *); 75 extern int ext2_directory_iterator_seek(ext2_directory_iterator_t *, aoff64_t pos); 75 76 extern int ext2_directory_iterator_fini(ext2_directory_iterator_t *); 76 77 -
uspace/srv/fs/ext2fs/ext2fs_ops.c
r911ee54 r4e36219 241 241 } 242 242 243 rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref );243 rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref, 0); 244 244 if (rc != EOK) { 245 245 return rc; … … 479 479 } 480 480 481 rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref );481 rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref, 0); 482 482 if (rc != EOK) { 483 483 EXT2FS_DBG("error %u", rc); … … 819 819 { 820 820 ext2_directory_iterator_t it; 821 aoff64_t cur;821 aoff64_t next; 822 822 uint8_t *buf; 823 823 size_t name_size; … … 825 825 bool found = false; 826 826 827 rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref );827 rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref, pos); 828 828 if (rc != EOK) { 829 829 async_answer_0(callid, rc); … … 832 832 } 833 833 834 /* Find the index we want to read 835 * Note that we need to iterate and count as 836 * the underlying structure is a linked list 837 * Moreover, we want to skip . and .. entries 834 /* Find next interesting directory entry. 835 * We want to skip . and .. entries 838 836 * as these are not used in HelenOS 839 837 */ 840 cur = 0;841 838 while (it.current != NULL) { 842 839 if (it.current->inode == 0) { … … 852 849 } 853 850 854 /* Is this the dir entry we want to read? */ 855 if (cur == pos) { 856 /* The on-disk entry does not contain \0 at the end 857 * end of entry name, so we copy it to new buffer 858 * and add the \0 at the end 859 */ 860 buf = malloc(name_size+1); 861 if (buf == NULL) { 862 ext2_directory_iterator_fini(&it); 863 async_answer_0(callid, ENOMEM); 864 async_answer_0(rid, ENOMEM); 865 return; 866 } 867 memcpy(buf, &it.current->name, name_size); 868 *(buf+name_size) = 0; 869 found = true; 870 (void) async_data_read_finalize(callid, buf, name_size+1); 871 free(buf); 872 break; 873 } 874 cur++; 851 /* The on-disk entry does not contain \0 at the end 852 * end of entry name, so we copy it to new buffer 853 * and add the \0 at the end 854 */ 855 buf = malloc(name_size+1); 856 if (buf == NULL) { 857 ext2_directory_iterator_fini(&it); 858 async_answer_0(callid, ENOMEM); 859 async_answer_0(rid, ENOMEM); 860 return; 861 } 862 memcpy(buf, &it.current->name, name_size); 863 *(buf+name_size) = 0; 864 found = true; 865 (void) async_data_read_finalize(callid, buf, name_size+1); 866 free(buf); 867 break; 875 868 876 869 skip: … … 884 877 } 885 878 879 if (found) { 880 rc = ext2_directory_iterator_next(&it); 881 if (rc != EOK) { 882 async_answer_0(rid, rc); 883 return; 884 } 885 next = it.current_offset; 886 } 887 886 888 rc = ext2_directory_iterator_fini(&it); 887 889 if (rc != EOK) { … … 891 893 892 894 if (found) { 893 async_answer_1(rid, EOK, 1);895 async_answer_1(rid, EOK, next-pos); 894 896 } 895 897 else {
Note:
See TracChangeset
for help on using the changeset viewer.