Changeset ad34feb in mainline for uspace/lib/ext2
- Timestamp:
- 2011-02-23T23:07:28Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 102d400
- Parents:
- a54af66
- Location:
- uspace/lib/ext2
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext2/libext2_filesystem.c
ra54af66 rad34feb 41 41 #include <libblock.h> 42 42 #include <malloc.h> 43 #include <assert.h> 43 44 44 45 /** … … 255 256 256 257 /** 258 * Find a filesystem block number where iblock-th data block 259 * of the given inode is located. 260 * 261 * @return EOK on success or negative error code on failure 262 */ 263 int ext2_filesystem_get_inode_data_block_index(ext2_filesystem_t *fs, ext2_inode_t* inode, 264 aoff64_t iblock, uint32_t* fblock) 265 { 266 int rc; 267 aoff64_t limits[4]; 268 uint32_t block_ids_per_block; 269 aoff64_t blocks_per_level[4]; 270 uint32_t offset_in_block; 271 uint32_t current_block; 272 aoff64_t block_offset_in_level; 273 int i; 274 int level; 275 block_t *block; 276 277 if (iblock < EXT2_INODE_DIRECT_BLOCKS) { 278 current_block = ext2_inode_get_direct_block(inode, (uint32_t)iblock); 279 if (current_block == 0) { 280 return EIO; 281 } 282 *fblock = current_block; 283 return EOK; 284 } 285 286 // Compute limits for indirect block levels 287 // TODO: compute this once when loading filesystem and store in ext2_filesystem_t 288 block_ids_per_block = ext2_superblock_get_block_size(fs->superblock) / sizeof(uint32_t); 289 limits[0] = EXT2_INODE_DIRECT_BLOCKS; 290 blocks_per_level[0] = 1; 291 for (i = 1; i < 4; i++) { 292 blocks_per_level[i] = blocks_per_level[i-1] * 293 block_ids_per_block; 294 limits[i] = limits[i-1] + blocks_per_level[i]; 295 } 296 297 // Determine the indirection level needed to get the desired block 298 level = -1; 299 for (i = 1; i < 4; i++) { 300 if (iblock < limits[i]) { 301 level = i; 302 break; 303 } 304 } 305 306 if (level == -1) { 307 return EIO; 308 } 309 310 block_offset_in_level = iblock - limits[level-1]; 311 current_block = ext2_inode_get_indirect_block(inode, level-1); 312 offset_in_block = block_offset_in_level / blocks_per_level[level-1]; 313 314 while (level > 0) { 315 rc = block_get(&block, fs->device, current_block, 0); 316 if (rc != EOK) { 317 return rc; 318 } 319 320 assert(offset_in_block < block_ids_per_block); 321 current_block = ((uint32_t*)block->data)[offset_in_block]; 322 323 rc = block_put(block); 324 if (rc != EOK) { 325 return rc; 326 } 327 328 if (current_block == 0) { 329 return EIO; 330 } 331 332 level -= 1; 333 334 if (level == 0) { 335 break; 336 } 337 338 offset_in_block = block_offset_in_level / blocks_per_level[level-1]; 339 block_offset_in_level %= blocks_per_level[level-1]; 340 } 341 342 *fblock = current_block; 343 344 return EOK; 345 } 346 347 /** 257 348 * Finalize an instance of filesystem 258 349 * -
uspace/lib/ext2/libext2_filesystem.h
ra54af66 rad34feb 60 60 ext2_inode_ref_t **); 61 61 extern int ext2_filesystem_put_inode_ref(ext2_inode_ref_t *); 62 extern int ext2_filesystem_get_inode_data_block_index(ext2_filesystem_t *, ext2_inode_t*, 63 aoff64_t, uint32_t*); 62 64 extern void ext2_filesystem_fini(ext2_filesystem_t *); 63 65 -
uspace/lib/ext2/libext2_inode.c
ra54af66 rad34feb 38 38 #include "libext2_superblock.h" 39 39 #include <byteorder.h> 40 #include <assert.h> 40 41 41 42 /** … … 142 143 143 144 /** 145 * Get number of blocks allocated for contents of the file 146 * represented by this inode. 147 * 148 * @param inode pointer to inode 149 */ 150 inline uint32_t ext2_inode_get_reserved_blocks(ext2_superblock_t *sb, 151 ext2_inode_t *inode) 152 { 153 return ext2_inode_get_reserved_512_blocks(inode) / 154 (ext2_superblock_get_block_size(sb) / 512); 155 } 156 157 /** 144 158 * Get inode flags 145 159 * … … 158 172 inline uint32_t ext2_inode_get_direct_block(ext2_inode_t *inode, uint8_t idx) 159 173 { 174 assert(idx < EXT2_INODE_DIRECT_BLOCKS); 160 175 return uint32_t_le2host(inode->direct_blocks[idx]); 161 176 } … … 165 180 * 166 181 * @param inode pointer to inode 182 * @param idx Indirection level. Valid values are 0 <= idx < 3, where 0 is 183 * singly-indirect block and 2 is triply-indirect-block 167 184 */ 168 inline uint32_t ext2_inode_get_ single_indirect_block(ext2_inode_t *inode)185 inline uint32_t ext2_inode_get_indirect_block(ext2_inode_t *inode, uint8_t idx) 169 186 { 170 return uint32_t_le2host(inode->single_indirect_block); 187 assert(idx < 3); 188 return uint32_t_le2host(inode->indirect_blocks[idx]); 171 189 } 172 173 /**174 * Get double indirect block ID175 *176 * @param inode pointer to inode177 */178 inline uint32_t ext2_inode_get_double_indirect_block(ext2_inode_t *inode)179 {180 return uint32_t_le2host(inode->double_indirect_block);181 }182 183 /**184 * Get triple indirect block ID185 *186 * @param inode pointer to inode187 */188 inline uint32_t ext2_inode_get_triple_indirect_block(ext2_inode_t *inode)189 {190 return uint32_t_le2host(inode->triple_indirect_block);191 }192 193 194 190 195 191 /** @} -
uspace/lib/ext2/libext2_inode.h
ra54af66 rad34feb 51 51 uint8_t unused2[4]; 52 52 uint32_t direct_blocks[12]; // Direct block ids stored in this inode 53 uint32_t single_indirect_block; 54 uint32_t double_indirect_block; 55 uint32_t triple_indirect_block; 53 uint32_t indirect_blocks[3]; 56 54 uint32_t version; 57 55 uint32_t file_acl; … … 75 73 #define EXT2_INODE_MODE_ACCESS_MASK 0x0FFF 76 74 #define EXT2_INODE_MODE_TYPE_MASK 0xF000 75 #define EXT2_INODE_DIRECT_BLOCKS 12 77 76 78 77 typedef struct ext2_inode_ref { … … 88 87 inline uint16_t ext2_inode_get_usage_count(ext2_inode_t *); 89 88 inline uint32_t ext2_inode_get_reserved_512_blocks(ext2_inode_t *); 89 inline uint32_t ext2_inode_get_reserved_blocks(ext2_superblock_t *, 90 ext2_inode_t *); 90 91 inline uint32_t ext2_inode_get_flags(ext2_inode_t *); 91 92 inline uint32_t ext2_inode_get_direct_block(ext2_inode_t *, uint8_t); 92 inline uint32_t ext2_inode_get_single_indirect_block(ext2_inode_t *); 93 inline uint32_t ext2_inode_get_double_indirect_block(ext2_inode_t *); 94 inline uint32_t ext2_inode_get_triple_indirect_block(ext2_inode_t *); 93 inline uint32_t ext2_inode_get_indirect_block(ext2_inode_t *, uint8_t level); 95 94 96 95
Note:
See TracChangeset
for help on using the changeset viewer.