| 434 | } |
| 435 | |
| 436 | uint32_t Ext2Volume::AllocateBlock(){ |
| 437 | for(unsigned i = 0; i < blockGroupCount; i++){ |
| 438 | ext2_blockgrp_desc_t& group = blockGroups[i]; |
| 439 | |
| 440 | if(group.freeBlockCount <= 0) continue; // No free blocks in this blockgroup |
| 441 | |
| 442 | uint8_t bitmap[blocksize / sizeof(uint8_t)]; |
| 443 | |
| 444 | if(uint8_t* cachedBitmap = bitmapCache.get(group.blockBitmap)){ |
| 445 | memcpy(bitmap, cachedBitmap, blocksize); |
| 446 | } else { |
| 447 | if(int e = ReadBlock(group.blockBitmap, bitmap)){ |
| 448 | Log::Error("[Ext2] Disk error (%d) reading block bitmap (group %d)", e, i); |
| 449 | error = DiskReadError; |
| 450 | return 0; |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | uint32_t block = 0; |
| 455 | unsigned e = 0; |
| 456 | for(; e < blocksize / sizeof(uint8_t); e++){ |
| 457 | if(bitmap[e] == UINT8_MAX) continue; // Full |
| 458 | |
| 459 | for(uint8_t b = 0; b < sizeof(uint8_t) * 8; b++){ // Iterate through all bits in the entry |
| 460 | if(((bitmap[e] >> b) & 0x1) == 0){ |
| 461 | bitmap[e] |= (1U << b); |
| 462 | block = (i * super.blocksPerGroup) + e * (sizeof(uint8_t) * 8) + b; // Block Number = (Group number * blocks per group) + (bitmap entry * 8 (8 bits per byte)) + bit (block 0 is least significant bit, block 7 is most significant) |
| 463 | break; |
| 464 | } |
| 465 | } |
| 466 | |
| 467 | |
| 468 | if(block) break; |
| 469 | } |
| 470 | |
| 471 | if(!block){ |
| 472 | continue; |
| 473 | } |
| 474 | |
| 475 | if(uint8_t* cachedBitmap = bitmapCache.get(group.blockBitmap)){ |
| 476 | memcpy(cachedBitmap, bitmap, blocksize); |
| 477 | } |
| 478 | |
| 479 | if(int e = WriteBlock(group.blockBitmap, bitmap)){ |
| 480 | Log::Error("[Ext2] Disk error (%d) write block bitmap (group %d)", e, i); |
| 481 | error = DiskWriteError; |
| 482 | return 0; |
| 483 | } |
| 484 | |
| 485 | super.freeBlockCount--; |
| 486 | blockGroups[i].freeBlockCount--; |
| 487 | |
| 488 | WriteBlockGroupDescriptor(i); |
| 489 | WriteSuperblock(); |
| 490 | |
| 491 | return block; |
| 492 | } |
| 493 | |