Changeset 786

Show
Ignore:
Timestamp:
07/13/08 20:44:09 (3 months ago)
Author:
mwhitworth
Message:

Add DestroyJournal, JournalSetUuid and JournalUpdateSuperblock code, along with other fixes.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • Whitix/branches/fs/fs/journal/journals.c

    r775 r786  
    2121#include <fs/vfs.h> 
    2222#include <init.h> 
     23#include <malloc.h> 
    2324#include <module.h> 
    2425#include <print.h> 
     
    3435int JournalBlockMap(struct Journal* journal, DWORD blockNo, DWORD* ret) 
    3536{ 
    36         int err; 
     37//      int err; 
    3738        struct VNode* vNode=journal->vNode; 
    3839 
     
    6263                buffer->privData=ret; 
    6364                ret->buffer=buffer; 
     65                INIT_WAITQUEUE_HEAD(&ret->wait); 
     66                 
    6467                BufferGet(buffer); 
    6568        } 
    6669 
    67         return buffer->privData; 
     70        return ret; 
     71} 
     72 
     73void JournalUpdateSuperBlock(struct Journal* journal) 
     74{ 
     75        DWORD blockNo; 
     76        struct Buffer* buffer; 
     77        struct JournalSuperBlock* jSb; 
     78         
     79        JournalBlockMap(journal, 0, &blockNo); 
     80         
     81        buffer=JournalBlockRead(journal, blockNo); 
     82         
     83        jSb=(struct JournalSuperBlock*)(buffer->data); 
     84         
     85        jSb->sequence=CpuToBe32(journal->tailSequence); 
     86        jSb->start=CpuToBe32(journal->tail); 
     87         
     88        BlockWrite(buffer->device, buffer); 
     89         
     90        WaitForBuffer(buffer); 
    6891} 
    6992 
     
    7497        /* Set up timer. */ 
    7598        commitTimer->func=SleepWakeup; 
    76         commitTimer->expires=journal->commitInterval*100000; 
     99        commitTimer->expires=journal->commitInterval*100000/HZ; 
    77100        commitTimer->data=currThread; 
    78101 
     
    97120        while (1) 
    98121        { 
     122                if (journal->flags & JOURN_UNMOUNT) 
     123                        break; 
     124                         
    99125                /* There should be a transaction to commit. */ 
    100126                if (journal->commitSequence != journal->commitRequest) 
    101127                { 
    102128                        TimerRemove(&commitTimer); 
    103  
    104129                        JournalCommitTransaction(journal); 
    105130                } 
     
    113138                ThrSchedule(); /* Will return here when the thread is scheduled again */ 
    114139                WaitRemoveFromQueue(&journal->commitWait, &commitWait); 
    115                  
     140 
    116141                /* Get the running transaction, if we timed out, and commit that. Check expires. */ 
    117142                if (journal->currTransaction && currTime.seconds >= journal->currTransaction->expires) 
    118143                        journal->commitRequest=journal->currTransaction->transId; 
    119144        } 
    120 } 
    121  
    122 int JournalWriteMetadataBuffer(struct JournalTrans* commmitTrans, struct JournalHead* old,  
    123         struct JournalHead* new, DWORD blockNo) 
    124 { 
    125         KePrint("JournalWriteMetadataBuffer\n"); 
     145         
     146        TimerRemove(&commitTimer); 
     147         
     148        journal->flags=0; 
     149        WakeUp(&journal->commitWaitDone); 
     150         
     151        ThrDoExitThread(); 
     152} 
     153 
     154int JournalWriteMetadataBuffer(struct JournalTrans* commitTrans, struct JournalHead* old,  
     155        struct JournalHead** new, DWORD blockNo) 
     156{ 
     157        struct Buffer* newBuf, *oldBuf; 
     158 
     159        oldBuf=JournHeadToBuffer(old); 
     160         
     161        newBuf=BlockBufferAlloc(oldBuf->device, blockNo); 
     162 
     163        /* Buffer is now locked, so copy over the data from old's buffer. */ 
     164        memcpy(newBuf->data, oldBuf->data, oldBuf->device->blockSize); 
     165 
     166        *new=JournalAddHeader(newBuf); 
     167        (*new)->transaction=NULL; 
     168         
     169        BufferUnlock(newBuf); 
     170 
     171        JournalFileBuffer(old, commitTrans, JOURN_SHADOW); 
     172        JournalFileBuffer(*new, commitTrans, JOURN_IO); 
    126173 
    127174        return 0; 
     
    162209        return JournalAddHeader(buffer); 
    163210} 
     211 
     212int JournalDestroy(struct Journal* journal) 
     213{ 
     214        /* Shutdown the committer thread. */ 
     215        journal->flags|=JOURN_UNMOUNT; 
     216        WakeUp(&journal->commitWait); 
     217        WAIT_ON(journal->commitWaitDone, !journal->flags); 
     218         
     219        if (journal->currTransaction) 
     220                JournalCommitTransaction(journal->currTransaction); 
     221                 
     222        JournalLock(journal); 
     223         
     224        JournalCheckpoint(journal); 
     225         
     226        journal->tail=0; 
     227        journal->tailSequence=++journal->transSequence; 
     228         
     229        JournalUpdateSuperBlock(journal); 
     230         
     231        VNodeRelease(journal->vNode); 
     232         
     233        JournalUnlock(journal);  
     234        MemCacheFree(journalCache, journal); 
     235         
     236        return 0;        
     237} 
     238 
     239SYMBOL_EXPORT(JournalDestroy); 
     240 
     241void JournalSetUuid(struct Journal* journal, BYTE* uuid) 
     242{ 
     243        memcpy(journal->uuid, uuid, 16); 
     244} 
     245 
     246SYMBOL_EXPORT(JournalSetUuid); 
    164247 
    165248struct Journal* JournalCreate(struct VNode* vNode) 
     
    177260 
    178261        journal->vNode=vNode; 
     262        ListRemove(&vNode->next); /* So that SysUnmount can unmount. Is this the right way to do it? */ 
    179263 
    180264        /* Read the journal superblock. */ 
    181265        JournalBlockMap(journal, 0, &blockNo); 
     266         
     267        if ((int)blockNo == -1) 
     268        { 
     269                KePrint(KERN_ERROR "JournalCreate: could not read the journal superblock\n"); 
     270                MemCacheFree(journalCache, journal); 
     271                return NULL; 
     272        } 
    182273 
    183274        headerBuf=JournalBlockRead(journal, blockNo); 
     
    209300        journal->maxLength=vNode->size/BYTES_PER_SECTOR(vNode->superBlock); 
    210301        journal->sectorSize=BYTES_PER_SECTOR(vNode->superBlock); 
    211         journal->transSequence=1; 
     302        journal->transSequence=1; /* Check */ 
    212303 
    213304        if (BeToCpu32(jSb->maxLen) < journal->maxLength) 
     
    230321        journal->commitSequence=journal->transSequence-1; 
    231322        journal->commitRequest=journal->commitSequence; 
    232  
    233         journal->head=BeToCpu32(jSb->first); 
     323        journal->tailSequence=journal->transSequence; 
     324 
     325        journal->head=journal->tail=BeToCpu32(jSb->first); 
    234326        journal->free=BeToCpu32(jSb->maxLen)-journal->head; 
    235327 
     328        INIT_LIST_HEAD(&journal->checkpointTrans); 
     329        INIT_WAITQUEUE_HEAD(&journal->waitUpdates); 
     330 
    236331        ThrStartThread(journal->commitThread); 
    237332 
     333        /* TODO: Wait for it to get started up before continuing */ 
     334 
    238335        return journal; 
    239336}