| 536 | } |
| 537 | |
| 538 | Ext2Node* Ext2Volume::CreateNode(){ |
| 539 | for(unsigned i = 0; i < blockGroupCount; i++){ |
| 540 | ext2_blockgrp_desc_t& group = blockGroups[i]; |
| 541 | |
| 542 | if(group.freeInodeCount <= 0) continue; // No free inodes in this blockgroup |
| 543 | |
| 544 | uint8_t bitmap[blocksize / sizeof(uint8_t)]; |
| 545 | |
| 546 | if(int e = ReadBlockCached(group.inodeBitmap, bitmap)){ |
| 547 | Log::Error("[Ext2] Disk error (%d) reading inode bitmap (group %d)", e, i); |
| 548 | error = DiskReadError; |
| 549 | return nullptr; |
| 550 | } |
| 551 | |
| 552 | uint32_t inode = 0; |
| 553 | |
| 554 | for(unsigned e = 0; e < blocksize / sizeof(uint8_t); e++){ |
| 555 | if(bitmap[e] == UINT8_MAX) continue; // Full |
| 556 | |
| 557 | for(uint8_t b = 0; b < sizeof(uint8_t) * 8; b++){ // Iterate through all bits in the entry |
| 558 | if(((bitmap[e] >> b) & 0x1) == 0){ |
| 559 | inode = (i * super.inodesPerGroup) + e * (sizeof(uint8_t) * 8) + b + 1; // Inode Number = (Group number * inodes per group) + (bitmap entry * 8 (8 bits per byte)) + bit (inode 1 is least significant bit, block 8 is most significant) + 1 (inodes start at 1) |
| 560 | |
| 561 | if((inode > superext.firstInode || super.revLevel == 0) && inode > 11){ |
| 562 | bitmap[e] |= (1U << b); |
| 563 | break; |
| 564 | } |
| 565 | } |
| 566 | } |
| 567 | |
| 568 | if(inode) break; |
| 569 | } |
| 570 | |
| 571 | if(!inode) continue; |
| 572 | |
| 573 | if(int e = WriteBlockCached(group.inodeBitmap, bitmap)){ |
| 574 | Log::Error("[Ext2] Disk error (%d) write inode bitmap (group %d)", e, i); |
| 575 | error = DiskWriteError; |
| 576 | return nullptr; |
| 577 | } |
| 578 | |
| 579 | ext2_inode_t ino; |
| 580 | |
| 581 | memset(&ino, 0, sizeof(ext2_inode_t)); |
| 582 | |
| 583 | ino.blocks[0] = AllocateBlock(); // Give it one block |
| 584 | ino.uid = 0; |
| 585 | ino.mode = 0; |
| 586 | ino.accessTime = ino.createTime = ino.deleteTime = ino.modTime = 0; |
| 587 | ino.gid = 0; |
| 588 | ino.blockCount = blocksize / 512; |
| 589 | ino.linkCount = 0; |
| 590 | ino.size = ino.sizeHigh = 0; |
| 591 | ino.fragAddr = 0; |
| 592 | ino.fileACL = 0; |
| 593 | |
| 594 | super.freeInodeCount--; |
| 595 | blockGroups[i].freeInodeCount--; |