| 36 | | }; |
| | 47 | .write = Ext3FileWrite, |
| | 48 | }; |
| | 49 | |
| | 50 | int Ext3FreeSuper(struct VfsSuperBlock* superBlock) |
| | 51 | { |
| | 52 | struct Ext3SbInfo* sb=EXT3_SUPERINFO(superBlock); |
| | 53 | |
| | 54 | if (sb && sb->journal) |
| | 55 | JournalDestroy(sb->journal); |
| | 56 | |
| | 57 | if (sb) |
| | 58 | free(sb); |
| | 59 | |
| | 60 | return 0; |
| | 61 | } |
| | 62 | |
| | 63 | int Ext3JournalSetup(struct VfsSuperBlock* superBlock, struct Ext3SuperBlock* sb, DWORD iNo) |
| | 64 | { |
| | 65 | struct VNode* journal; |
| | 66 | |
| | 67 | journal=VNodeGet(superBlock, iNo); |
| | 68 | |
| | 69 | if (!journal) |
| | 70 | { |
| | 71 | KePrint("EXT3: no journal found\n"); |
| | 72 | return 0; |
| | 73 | } |
| | 74 | |
| | 75 | if (!journal->size) |
| | 76 | { |
| | 77 | KePrint(KERN_ERROR "EXT3: Zero length journal present\n"); |
| | 78 | return -EINVAL; |
| | 79 | } |
| | 80 | |
| | 81 | /* The journal node must be used (i.e. linked to somewhere). Check! */ |
| | 82 | |
| | 83 | KePrint("EXT3: Found journal at %#X: size = %#X\n", iNo, journal->size); |
| | 84 | |
| | 85 | /* Let the journal layer handle the replaying. */ |
| | 86 | EXT3_SUPERINFO(superBlock)->journal=JournalCreate(journal); |
| | 87 | |
| | 88 | if (!journal) |
| | 89 | return -EIO; |
| | 90 | |
| | 91 | JournalSetUuid(EXT3_SUPERINFO(superBlock)->journal, sb->journalUuid); |
| | 92 | |
| | 93 | return 0; |
| | 94 | } |
| | 95 | |
| | 96 | int Ext3JournalInit(struct VfsSuperBlock* superBlock, struct Ext3SuperBlock* sb) |
| | 97 | { |
| | 98 | /* TODO: Recovery? */ |
| | 99 | |
| | 100 | if (sb->journalINum) |
| | 101 | { |
| | 102 | return Ext3JournalSetup(superBlock, sb, sb->journalINum); |
| | 103 | }else |
| | 104 | KePrint("Ext3JournalInit: get dev journal\n"); |
| | 105 | |
| | 106 | return -ENOTIMPL; |
| | 107 | } |
| | 108 | |
| | 109 | DWORD Ext3GetDescriptorLoc(struct VfsSuperBlock* superBlock, int i) |
| | 110 | { |
| | 111 | struct Ext3SbInfo* sb=EXT3_SUPERINFO(superBlock); |
| | 112 | // unsigned long block; |
| | 113 | |
| | 114 | return sb->sbSector+i+1; |
| | 115 | |
| | 116 | /* Check features for meta block group */ |
| | 117 | #if 0 |
| | 118 | block=DESCS_PER_BLOCK(superBlock)*i; |
| | 119 | |
| | 120 | return sb->firstDataBlock+(block*sb->blocksPerGrp); |
| | 121 | #endif |
| | 122 | } |
| | 123 | |
| | 124 | int Ext3ReadSuperBlock(struct VfsSuperBlock* superBlock, struct Ext3SbInfo* sbInfo) |
| | 125 | { |
| | 126 | int sector, offset; |
| | 127 | |
| | 128 | sector=1*1024/BYTES_PER_SECTOR(superBlock); |
| | 129 | offset=(1*1024) % BYTES_PER_SECTOR(superBlock); |
| | 130 | |
| | 131 | sbInfo->sbBuffer=BlockRead(superBlock->sDevice, sector); |
| | 132 | |
| | 133 | if (!sbInfo->sbBuffer) |
| | 134 | return -EIO; |
| | 135 | |
| | 136 | sbInfo->super=(struct Ext3SuperBlock*)((sbInfo->sbBuffer->data)+offset); |
| | 137 | sbInfo->sbSector=sector; |
| | 138 | |
| | 139 | return 0; |
| | 140 | } |
| 71 | | sbInfo->iNodesCount=sb->iNodesCount; |
| 72 | | sbInfo->groupCount=(sb->blocksCount-sb->firstDataBlock+sb->blocksPerGrp-1)/sb->blocksPerGrp; |
| 73 | | sbInfo->iNodesPerGrp=sb->iNodesPerGrp; |
| | 182 | sbInfo->iNodesCount=sb.iNodesCount; |
| | 183 | sbInfo->blocksPerGrp=sb.blocksPerGrp; |
| | 184 | sbInfo->groupCount=(sb.blocksCount-sb.firstDataBlock+sb.blocksPerGrp-1)/sb.blocksPerGrp; |
| | 185 | sbInfo->iNodesPerGrp=sb.iNodesPerGrp; |
| | 186 | |
| | 187 | sbInfo->firstDataBlock=sb.firstDataBlock; |
| | 188 | |
| | 189 | /* Read in the superblock again. */ |
| | 190 | Ext3ReadSuperBlock(retVal, sbInfo); |
| | 191 | |
| | 192 | /* And set the Ext3-specific parts of the superblock structure. */ |
| | 193 | retVal->privData=sbInfo; |
| | 194 | retVal->sbOps=&ext3SbOps; |
| 80 | | sbInfo->descs[i]=BlockRead(dev,2+i); |
| 81 | | |
| 82 | | /* And set the Ext3-specific parts of the superblock structure. */ |
| 83 | | retVal->privData=sbInfo; |
| 84 | | retVal->sbOps=&ext3SbOps; |
| 85 | | |
| 86 | | /* For now */ |
| 87 | | retVal->flags|=SB_RDONLY; |
| 88 | | |
| 89 | | /* Ext3 block sizes are a multiple of 1024. */ |
| 90 | | BlockSetSize(dev,1024 << sb->logBlockSize); |
| | 204 | sbInfo->descs[i]=BlockRead(dev, Ext3GetDescriptorLoc(retVal, i)); |
| | 205 | |
| | 206 | /* If we have a journal, read it in. We read the journal in before the root |
| | 207 | * node, because it may have been modified in the journal. */ |
| | 208 | |
| | 209 | if (EXT3_FEATURE_COMPAT(&sb, EXT3_FEATURE_COMPAT_JOURNAL)) |
| | 210 | { |
| | 211 | if (Ext3JournalInit(retVal, &sb)) |
| | 212 | goto descsFree; |
| | 213 | |
| | 214 | /* Write journal superblock. */ |
| | 215 | } |