Changeset a8e1aae in mainline for uspace/lib/ext2/libext2_directory.c
- Timestamp:
- 2011-02-24T21:03:42Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9ffbdf1
- Parents:
- 102d400
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext2/libext2_directory.c
r102d400 ra8e1aae 37 37 #include "libext2_directory.h" 38 38 #include <byteorder.h> 39 #include <errno.h> 40 #include <assert.h> 39 41 40 42 /** … … 75 77 } 76 78 79 /** 80 * Initialize a directory iterator 81 * 82 * @param it pointer to iterator to initialize 83 * @param fs pointer to filesystem structure 84 * @param inode pointer to inode reference structure 85 * @return EOK on success or negative error code on failure 86 */ 87 int ext2_directory_iterator_init(ext2_directory_iterator_t *it, 88 ext2_filesystem_t *fs, ext2_inode_ref_t *inode_ref) 89 { 90 int rc; 91 uint32_t block_id; 92 it->inode_ref = inode_ref; 93 it->fs = fs; 94 95 // Get the first data block, so we can get first entry 96 rc = ext2_filesystem_get_inode_data_block_index(fs, inode_ref->inode, 0, 97 &block_id); 98 if (rc != EOK) { 99 return rc; 100 } 101 102 rc = block_get(&it->current_block, fs->device, block_id, 0); 103 if (rc != EOK) { 104 return rc; 105 } 106 107 it->current = it->current_block->data; 108 it->current_offset = 0; 109 110 return EOK; 111 } 112 113 /** 114 * Advance the directory iterator to the next entry 115 * 116 * @param it pointer to iterator to initialize 117 * @return EOK on success or negative error code on failure 118 */ 119 int ext2_directory_iterator_next(ext2_directory_iterator_t *it) 120 { 121 int rc; 122 uint16_t skip; 123 uint64_t size; 124 aoff64_t current_block_idx; 125 aoff64_t next_block_idx; 126 uint32_t next_block_phys_idx; 127 uint32_t block_size; 128 uint32_t offset_in_block; 129 130 assert(it->current != NULL); 131 132 skip = ext2_directory_entry_ll_get_entry_length(it->current); 133 size = ext2_inode_get_size(it->fs->superblock, it->inode_ref->inode); 134 135 // Are we at the end? 136 if (it->current_offset + skip >= size) { 137 rc = block_put(it->current_block); 138 it->current_block = NULL; 139 it->current = NULL; 140 if (rc != EOK) { 141 return rc; 142 } 143 144 it->current_offset += skip; 145 return EOK; 146 } 147 148 block_size = ext2_superblock_get_block_size(it->fs->superblock); 149 current_block_idx = it->current_offset / block_size; 150 next_block_idx = (it->current_offset + skip) / block_size; 151 152 // If we are moving accross block boundary, 153 // we need to get another block 154 if (current_block_idx != next_block_idx) { 155 rc = block_put(it->current_block); 156 it->current_block = NULL; 157 it->current = NULL; 158 if (rc != EOK) { 159 return rc; 160 } 161 162 rc = ext2_filesystem_get_inode_data_block_index(it->fs, 163 it->inode_ref->inode, next_block_idx, &next_block_phys_idx); 164 if (rc != EOK) { 165 return rc; 166 } 167 168 rc = block_get(&it->current_block, it->fs->device, next_block_phys_idx, 169 BLOCK_FLAGS_NONE); 170 if (rc != EOK) { 171 it->current_block = NULL; 172 return rc; 173 } 174 } 175 176 offset_in_block = (it->current_offset + skip) % block_size; 177 178 // Ensure proper alignment 179 if ((offset_in_block % 4) != 0) { 180 it->current = NULL; 181 return EIO; 182 } 183 184 // Ensure that the core of the entry does not overflow the block 185 if (offset_in_block > block_size - 8) { 186 it->current = NULL; 187 return EIO; 188 } 189 190 it->current = it->current_block->data + offset_in_block; 191 it->current_offset += skip; 192 193 // Ensure that the whole entry does not overflow the block 194 skip = ext2_directory_entry_ll_get_entry_length(it->current); 195 if (offset_in_block + skip > block_size) { 196 it->current = NULL; 197 return EIO; 198 } 199 200 // Ensure the name length is not too large 201 if (ext2_directory_entry_ll_get_name_length(it->fs->superblock, 202 it->current) > skip-8) { 203 it->current = NULL; 204 return EIO; 205 } 206 207 return EOK; 208 } 209 210 /** 211 * Release all resources asociated with the directory iterator 212 * 213 * @param it pointer to iterator to initialize 214 * @return EOK on success or negative error code on failure 215 */ 216 int ext2_directory_iterator_fini(ext2_directory_iterator_t *it) 217 { 218 int rc; 219 220 it->fs = NULL; 221 it->inode_ref = NULL; 222 it->current = NULL; 223 224 if (it->current_block) { 225 rc = block_put(it->current_block); 226 if (rc != EOK) { 227 return rc; 228 } 229 } 230 231 return EOK; 232 } 233 77 234 /** @} 78 235 */
Note:
See TracChangeset
for help on using the changeset viewer.