Changes in / [b5085a7:9e34750] in mainline
- Location:
- uspace
- Files:
-
- 4 edited
-
app/ext2info/ext2info.c (modified) (1 diff)
-
lib/ext2/libext2_directory.c (modified) (5 diffs)
-
lib/ext2/libext2_directory.h (modified) (1 diff)
-
srv/fs/ext2fs/ext2fs_ops.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/ext2info/ext2info.c
rb5085a7 r9e34750 590 590 printf(" Directory contents:\n"); 591 591 592 rc = ext2_directory_iterator_init(&it, fs, inode_ref , 0);592 rc = ext2_directory_iterator_init(&it, fs, inode_ref); 593 593 if (rc != EOK) { 594 594 printf("Failed initializing directory iterator\n"); -
uspace/lib/ext2/libext2_directory.c
rb5085a7 r9e34750 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 entry89 88 * @return EOK on success or negative error code on failure 90 89 */ 91 90 int ext2_directory_iterator_init(ext2_directory_iterator_t *it, 92 ext2_filesystem_t *fs, ext2_inode_ref_t *inode_ref, aoff64_t pos) 93 { 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 94 97 it->inode_ref = inode_ref; 95 98 it->fs = fs; 96 it->current = NULL; 97 it->current_offset = 0; 98 it->current_block = NULL; 99 100 return ext2_directory_iterator_seek(it, pos); 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); 101 116 } 102 117 … … 109 124 int ext2_directory_iterator_next(ext2_directory_iterator_t *it) 110 125 { 126 int rc; 111 127 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 initialize124 * @return EOK on success or negative error code on failure125 */126 int ext2_directory_iterator_seek(ext2_directory_iterator_t *it, aoff64_t pos)127 {128 int rc;129 130 128 uint64_t size; 131 129 aoff64_t current_block_idx; … … 134 132 uint32_t block_size; 135 133 134 assert(it->current != NULL); 135 136 skip = ext2_directory_entry_ll_get_entry_length(it->current); 136 137 size = ext2_inode_get_size(it->fs->superblock, it->inode_ref->inode); 137 138 138 /* The iterator is not valid until we seek to the desired position */139 it->current = NULL;140 141 139 /* Are we at the end? */ 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 } 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; 149 146 } 150 147 151 it->current_offset = pos;148 it->current_offset += skip; 152 149 return EOK; 153 150 } … … 155 152 block_size = ext2_superblock_get_block_size(it->fs->superblock); 156 153 current_block_idx = it->current_offset / block_size; 157 next_block_idx = pos/ block_size;158 159 /* If we don't have a block orare moving accross block boundary,154 next_block_idx = (it->current_offset + skip) / block_size; 155 156 /* If we are moving accross block boundary, 160 157 * we need to get another block 161 158 */ 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 } 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; 169 165 } 170 166 … … 183 179 } 184 180 185 it->current_offset = pos;181 it->current_offset += skip; 186 182 return ext2_directory_iterator_set(it, block_size); 187 183 } 188 184 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 failure195 */196 185 static int ext2_directory_iterator_set(ext2_directory_iterator_t *it, 197 186 uint32_t block_size) -
uspace/lib/ext2/libext2_directory.h
rb5085a7 r9e34750 71 71 72 72 extern int ext2_directory_iterator_init(ext2_directory_iterator_t *, 73 ext2_filesystem_t *, ext2_inode_ref_t * , aoff64_t);73 ext2_filesystem_t *, ext2_inode_ref_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);76 75 extern int ext2_directory_iterator_fini(ext2_directory_iterator_t *); 77 76 -
uspace/srv/fs/ext2fs/ext2fs_ops.c
rb5085a7 r9e34750 240 240 } 241 241 242 rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref , 0);242 rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref); 243 243 if (rc != EOK) { 244 244 return rc; … … 478 478 } 479 479 480 rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref , 0);480 rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref); 481 481 if (rc != EOK) { 482 482 EXT2FS_DBG("error %u", rc); … … 818 818 { 819 819 ext2_directory_iterator_t it; 820 aoff64_t next;820 aoff64_t cur; 821 821 uint8_t *buf; 822 822 size_t name_size; … … 824 824 bool found = false; 825 825 826 rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref , pos);826 rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref); 827 827 if (rc != EOK) { 828 828 async_answer_0(callid, rc); … … 831 831 } 832 832 833 /* Find next interesting directory entry. 834 * We want to skip . and .. entries 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 835 837 * as these are not used in HelenOS 836 838 */ 839 cur = 0; 837 840 while (it.current != NULL) { 838 841 if (it.current->inode == 0) { … … 848 851 } 849 852 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; 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; 860 872 } 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; 873 cur++; 867 874 868 875 skip: … … 876 883 } 877 884 885 rc = ext2_directory_iterator_fini(&it); 886 if (rc != EOK) { 887 async_answer_0(rid, rc); 888 return; 889 } 890 878 891 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 887 rc = ext2_directory_iterator_fini(&it); 888 if (rc != EOK) { 889 async_answer_0(rid, rc); 890 return; 891 } 892 893 if (found) { 894 async_answer_1(rid, EOK, next-pos); 892 async_answer_1(rid, EOK, 1); 895 893 } 896 894 else {
Note:
See TracChangeset
for help on using the changeset viewer.
