Show
Ignore:
Timestamp:
08/21/08 21:52:46 (4 years ago)
Author:
mwhitworth
Message:

Merge ext3 into trunk.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • Whitix/trunk/fs/ext3/super.c

    r608 r858  
    2121#include <malloc.h> 
    2222#include <error.h> 
     23#include <print.h> 
     24 
     25int Ext3FreeSuper(struct VfsSuperBlock* superBlock); 
    2326 
    2427struct SuperBlockOps ext3SbOps={ 
    2528        .readVNode = Ext3ReadVNode, 
     29        .writeVNode = Ext3WriteVNode, 
     30        .dirtyVNode = Ext3DirtyVNode, 
     31        .freeSuper = Ext3FreeSuper, 
    2632}; 
    2733 
     
    2935        .lookup = Ext3Lookup, 
    3036        .blockMap = Ext3BlockMap, 
     37        .create = Ext3Create, 
     38        .remove = Ext3Remove, 
     39        .truncate = Ext3Truncate, 
     40        .mkDir = Ext3MkDir, 
     41        .rmDir = Ext3RemoveDir, 
    3142}; 
    3243 
     
    3445        .readDir = Ext3ReadDir, 
    3546        .read = FileGenericRead, 
    36 }; 
     47        .write = Ext3FileWrite, 
     48}; 
     49 
     50int 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 
     63int 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 
     96int 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 
     109DWORD 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 
     124int 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} 
    37141 
    38142struct VfsSuperBlock* Ext3ReadSuper(struct StorageDevice* dev,int flags,char* data) 
     
    40144        struct VfsSuperBlock* retVal; 
    41145        struct Buffer* buff; 
    42         struct Ext3SuperBlock* sb; 
     146        struct Ext3SuperBlock sb; 
    43147        struct Ext3SbInfo* sbInfo; 
    44148        int descCount,i; 
     
    54158                goto error; 
    55159 
    56         sb=(struct Ext3SuperBlock*)buff->data; 
     160        /* The buffer will be freed if we set the block size to something other than 
     161         * 1024, so save the data off now. 
     162         */ 
     163 
     164        memcpy(&sb, buff->data, sizeof(struct Ext3SuperBlock)); 
    57165 
    58166        /* Sanity check. */ 
    59         if (sb->magic != EXT3_SB_MAGIC) 
     167        if (sb.magic != EXT3_SB_MAGIC) 
    60168                goto blockReadError; 
    61169 
     
    63171        if (!retVal) 
    64172                goto blockReadError; 
     173 
     174        /* Ext3 block sizes are a multiple of 1024. */ 
     175        BlockSetSize(dev,1024 << sb.logBlockSize); 
    65176 
    66177        /* Copy some useful information over into the private superblock structure. */ 
     
    69180                goto superFreeError; 
    70181 
    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; 
    74195 
    75196        /* Read in the block descriptors as pointers to buffers. */ 
     
    77198        sbInfo->descs=(struct Buffer**)malloc(descCount*sizeof(struct Buffer*)); 
    78199 
     200        if (!descCount) 
     201                goto superFreeError; 
     202 
    79203        for (i=0; i<descCount; i++) 
    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        } 
    91216 
    92217        retVal->mount=VNodeGet(retVal, EXT3_ROOT_VNO);