void FileSystemUnix::resolveIndirectDataBlocks(Inode* inode, sector_addr_t indirect_block, uint16 degree_of_indirection, uint16 sector_addr_len) { if(indirect_block == UNUSED_DATA_BLOCK) { debug(FS_UNIX, "resolveIndirectDataBlocks - indirect_block is not in use - quit\n"); return; } if(degree_of_indirection == 0) { debug(FS_UNIX, "resolveIndirectDataBlocks - sorry this method only works for indirect blocks - quit\n"); return; } debug(FS_UNIX, "resolveIndirectDataBlocks - indirect_block %x deg_of_indirection=%d\n", indirect_block, degree_of_indirection); FileSystem* fs = inode->getFileSystem(); assert(fs != NULL); FsVolumeManager* volume_manager = fs->getVolumeManager(); assert(volume_manager != NULL); // lock sector for reading volume_manager->acquireDataBlockForReading(indirect_block); // readout sector data char* sector = volume_manager->readDataBlockUnprotected(indirect_block); // scan the current block for more indirect blocks for(sector_len_t i = 0; i < fs->getDataBlockSize(); i+= sector_addr_len) { sector_addr_t new_sector = 0; // reading the current sector entry in a very flexible way for(uint16 j = 0; j < sector_addr_len; j++) { //debug(FS_UNIX, "resolveIndirectDataBlocks - sector[%d + %d]=%x\n", i, j, (uint8)sector[i + j]); new_sector |= ((uint8)(sector[i + j])) << (8*j); } if(new_sector == UNUSED_DATA_BLOCK) { // from here on there are no more indirect blocks to resolve, we can quit debug(FS_UNIX, "resolveIndirectDataBlocks - quit search for indirect blocks\n"); break; } debug(FS_UNIX, "resolveIndirectDataBlocks - new_sector=%x\n", new_sector); // single-indirect block means that the gained (resolved) sector-address // points to a data-block of the i_node if(degree_of_indirection == 1) { inode->addSector(new_sector); } else { resolveIndirectDataBlocks(inode, new_sector, degree_of_indirection-1, sector_addr_len); } } volume_manager->releaseReadDataBlock(indirect_block); delete[] sector; }