Show
Ignore:
Timestamp:
07/09/08 15:26:36 (5 months ago)
Author:
mwhitworth
Message:

Add to journal code. Support for per-journal threads, flushing of metadata, and start of commit code.

Files:
1 modified

Legend:

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

    r756 r759  
    4444} 
    4545 
     46struct JournalHead* JournalAllocHeader() 
     47{ 
     48        return malloc(sizeof(struct JournalHead)); 
     49} 
     50 
     51struct JournalHead* JournalAddHeader(struct Buffer* buffer) 
     52{ 
     53        struct JournalHead* ret; 
     54 
     55        if (BufferJournal(buffer)) 
     56        { 
     57                ret=BufferToJournHead(buffer); 
     58        }else{ 
     59                ret=JournalAllocHeader(); 
     60 
     61                buffer->flags |= 1 << BUFFER_JOURNAL; 
     62                buffer->privData=ret; 
     63                ret->buffer=buffer; 
     64                BufferGet(buffer); 
     65        } 
     66 
     67        return buffer->privData; 
     68} 
     69 
     70extern void SleepWakeup(void* data); 
     71 
     72void JournalCommitSetTimer(struct Timer* commitTimer, struct Journal* journal) 
     73{ 
     74        /* Set up timer. */ 
     75        commitTimer->func=SleepWakeup; 
     76        commitTimer->expires=journal->commitInterval*100000; 
     77        commitTimer->data=currThread; 
     78 
     79        TimerAdd(commitTimer); 
     80} 
     81 
     82/* Journal commit thread. */ 
     83 
     84/* TODO: Move to commit.c */ 
     85void JournalCommitter(void* arg) 
     86{ 
     87        struct Journal* journal=(struct Journal*)arg; 
     88        struct Timer commitTimer; 
     89        INIT_WAITQUEUE_ENTRY(commitWait); 
     90 
     91        INIT_WAITQUEUE_HEAD(&journal->commitWait); 
     92        INIT_WAITQUEUE_HEAD(&journal->commitWaitDone); 
     93 
     94        KePrint(KERN_INFO "JournalCommitter: started journal with commit interval of %d" 
     95                " seconds\n", journal->commitInterval); 
     96 
     97        while (1) 
     98        { 
     99                /* There should be a transaction to commit. */ 
     100                if (journal->commitSequence != journal->commitRequest) 
     101                { 
     102                        TimerRemove(&commitTimer); 
     103 
     104                        JournalCommitTransaction(journal); 
     105                } 
     106 
     107                /* May not always want timer running, esp. if we are waiting for commits. */ 
     108                JournalCommitSetTimer(&commitTimer, journal); 
     109 
     110                WaitAddToQueue(&journal->commitWait, &commitWait); 
     111 
     112                ThrSuspendThread(currThread); 
     113                ThrSchedule(); /* Will return here when the thread is scheduled again */ 
     114                WaitRemoveFromQueue(&journal->commitWait, &commitWait); 
     115                 
     116                /* Get the running transaction, if we timed out, and commit that. Check expires. */ 
     117                if (journal->currTransaction && currTime.seconds >= journal->currTransaction->expires) 
     118                        journal->commitRequest=journal->currTransaction->transId; 
     119        } 
     120} 
     121 
     122int JournalNextLogBlock(struct Journal* journal, DWORD* ret) 
     123{ 
     124        DWORD blockNum; 
     125 
     126        blockNum=journal->head; 
     127 
     128        journal->head++; 
     129        journal->free--; 
     130         
     131        /* Check for wraparound! */ 
     132 
     133        return JournalBlockMap(journal, blockNum, ret); 
     134} 
     135 
     136struct JournalHead* JournalGetDescriptorBuffer(struct Journal* journal) 
     137{ 
     138        int err; 
     139        DWORD blockNum; 
     140        struct Buffer* buffer; 
     141 
     142        err=JournalNextLogBlock(journal, &blockNum); 
     143 
     144        if (err) 
     145                return NULL; 
     146 
     147        buffer=JournalBlockRead(journal, blockNum); 
     148 
     149        if (!buffer) 
     150                return NULL; 
     151 
     152        memset(buffer->data, 0, journal->sectorSize); 
     153 
     154        return JournalAddHeader(buffer); 
     155} 
     156 
    46157struct Journal* JournalCreate(struct VNode* vNode) 
    47158{ 
    48         struct Journal* journal=JournalAllocate(); 
     159        struct Journal* journal; 
    49160        DWORD blockNo; 
    50161        struct Buffer* headerBuf; 
     
    52163        struct VfsSuperBlock* superBlock=vNode->superBlock; 
    53164 
     165        journal=JournalAllocate(); 
     166 
    54167        if (!journal) 
    55168                return NULL; 
     
    100213                journal->version, journal->maxLength); 
    101214 
     215        /* Start the per-journal commit kernel thread. */ 
     216        journal->commitThread=ThrCreateKernelThreadArg(JournalCommitter, journal); 
     217        journal->commitInterval=JOURN_COMMIT_INTERVAL; 
     218 
     219        JournalRecover(journal, jSb); 
     220 
     221        /* Set up transaction sequence numbers. */ 
     222        journal->commitSequence=journal->transSequence-1; 
     223        journal->commitRequest=journal->commitSequence; 
     224 
     225        journal->head=BeToCpu32(jSb->first); 
     226        journal->free=BeToCpu32(jSb->maxLen)-journal->head; 
     227 
     228        ThrStartThread(journal->commitThread); 
     229 
    102230        return journal; 
    103231}