Changeset 759 for Whitix/branches
- Timestamp:
- 07/09/08 15:26:36 (5 months ago)
- Location:
- Whitix/branches/fs/fs/journal
- Files:
-
- 3 modified
-
init.c (modified) (2 diffs)
-
journals.c (modified) (3 diffs)
-
transaction.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
Whitix/branches/fs/fs/journal/init.c
r756 r759 28 28 struct Cache* journalCache=NULL, *journHandleCache=NULL, *journTransCache=NULL; 29 29 30 static void JournalCommitter()31 {32 ThrSetPriority(currThread, 1);33 34 while (1)35 {36 ThrSuspendThread(currThread);37 ThrSchedule();38 39 KePrint("JournalCommitter was woken up\n");40 }41 }42 43 30 int JournalInit() 44 31 { … … 50 37 sizeof(struct JournalTrans), NULL, NULL, 0); 51 38 52 journalCommitter=ThrCreateKernelThread(JournalCommitter);53 54 39 return 0; 55 40 } -
Whitix/branches/fs/fs/journal/journals.c
r756 r759 44 44 } 45 45 46 struct JournalHead* JournalAllocHeader() 47 { 48 return malloc(sizeof(struct JournalHead)); 49 } 50 51 struct 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 70 extern void SleepWakeup(void* data); 71 72 void 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 */ 85 void 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 122 int 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 136 struct 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 46 157 struct Journal* JournalCreate(struct VNode* vNode) 47 158 { 48 struct Journal* journal =JournalAllocate();159 struct Journal* journal; 49 160 DWORD blockNo; 50 161 struct Buffer* headerBuf; … … 52 163 struct VfsSuperBlock* superBlock=vNode->superBlock; 53 164 165 journal=JournalAllocate(); 166 54 167 if (!journal) 55 168 return NULL; … … 100 213 journal->version, journal->maxLength); 101 214 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 102 230 return journal; 103 231 } -
Whitix/branches/fs/fs/journal/transaction.c
r756 r759 18 18 19 19 #include <fs/journal.h> 20 #include <fs/vfs.h> 20 21 #include <module.h> 21 22 #include <print.h> … … 51 52 ret->state=JTRANS_RUNNING; 52 53 ret->transId=journal->transSequence++; 54 ret->expires=currTime.seconds+JOURN_COMMIT_INTERVAL; 55 56 /* TODO: Move to constructor. */ 57 INIT_LIST_HEAD(&ret->reservedList); 58 INIT_LIST_HEAD(&ret->metaDataList); 53 59 54 60 /* TODO: Set up timer. */ … … 148 154 SYMBOL_EXPORT(JournalStart); 149 155 156 int JournalStop(struct JournalHandle* handle) 157 { 158 struct JournalTrans* trans=handle->transaction; 159 struct Journal* journal=trans->journal; 160 161 currThread->currHandle=NULL; 162 163 trans->updates--; 164 trans->outstandingBlocks-=handle->numBlocks; 165 166 if (!trans->updates) 167 { 168 /* Wake up waiters. */ 169 } 170 171 if (handle->sync == 1 || currTime.seconds >= trans->expires) 172 { 173 int id=trans->transId; 174 175 JournalStartCommit(journal, trans); 176 177 if (handle->sync == 1) 178 JournalWaitCommit(journal, id); 179 } 180 181 MemCacheFree(journHandleCache, handle); 182 183 return 0; 184 } 185 186 SYMBOL_EXPORT(JournalStop); 187 188 void JournalFileBuffer(struct JournalHead* head, struct JournalTrans* trans, int type) 189 { 190 struct ListHead* list; 191 192 /* Already filed? */ 193 if (head->transaction && head->list == type) 194 return; 195 196 /* 197 * It's already in this transaction, but on a different list, so we remove it 198 * before adding it to the other list. 199 */ 200 201 if (head->transaction == trans && head->list > 0 && head->list != type) 202 ListRemove(&head->next); 203 204 switch (type) 205 { 206 case JOURN_RESERVED: 207 list=&trans->reservedList; 208 break; 209 210 case JOURN_METADATA: 211 list=&trans->metaDataList; 212 break; 213 214 default: 215 KePrint("FileBuffer: handle %d!\n", type); 216 return; 217 } 218 219 ListAddTail(&head->next, list); 220 head->list=type; 221 } 222 150 223 /* Intent to modify a buffer for metadata update. */ 151 224 … … 158 231 head=JournalAddHeader(buffer); 159 232 233 JournalLock(journal); 234 235 /* Check if buffer is locked. */ 236 237 if (!head->transaction) 238 { 239 head->transaction=trans; 240 JournalFileBuffer(head, trans, JOURN_RESERVED); 241 } 242 243 JournalUnlock(journal); 244 160 245 return 0; 161 246 } 162 247 163 248 SYMBOL_EXPORT(JournalGetWriteAccess); 249 250 int JournalDirtyMetadata(struct JournalHandle* handle, struct Buffer* buffer) 251 { 252 struct JournalTrans* trans=handle->transaction; 253 struct Journal* journal=trans->journal; 254 struct JournalHead* head=BufferToJournHead(buffer); 255 256 JournalLock(journal); 257 258 JournalFileBuffer(head, trans, JOURN_METADATA); 259 260 JournalUnlock(journal); 261 262 return 0; 263 } 264 265 SYMBOL_EXPORT(JournalDirtyMetadata); 266 267 int JournalForceCommit(struct Journal* journal) 268 { 269 struct JournalHandle* handle; 270 271 handle=JournalStart(journal, 1); 272 273 handle->sync=1; 274 275 /* The sync forces the commit to disk. */ 276 JournalStop(handle); 277 278 return 0; 279 } 280 281 SYMBOL_EXPORT(JournalForceCommit);