Changeset 786 for Whitix/branches/fs/fs/journal/journals.c
- Timestamp:
- 07/13/08 20:44:09 (5 months ago)
- Files:
-
- 1 modified
-
Whitix/branches/fs/fs/journal/journals.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
Whitix/branches/fs/fs/journal/journals.c
r775 r786 21 21 #include <fs/vfs.h> 22 22 #include <init.h> 23 #include <malloc.h> 23 24 #include <module.h> 24 25 #include <print.h> … … 34 35 int JournalBlockMap(struct Journal* journal, DWORD blockNo, DWORD* ret) 35 36 { 36 int err;37 // int err; 37 38 struct VNode* vNode=journal->vNode; 38 39 … … 62 63 buffer->privData=ret; 63 64 ret->buffer=buffer; 65 INIT_WAITQUEUE_HEAD(&ret->wait); 66 64 67 BufferGet(buffer); 65 68 } 66 69 67 return buffer->privData; 70 return ret; 71 } 72 73 void 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); 68 91 } 69 92 … … 74 97 /* Set up timer. */ 75 98 commitTimer->func=SleepWakeup; 76 commitTimer->expires=journal->commitInterval*100000 ;99 commitTimer->expires=journal->commitInterval*100000/HZ; 77 100 commitTimer->data=currThread; 78 101 … … 97 120 while (1) 98 121 { 122 if (journal->flags & JOURN_UNMOUNT) 123 break; 124 99 125 /* There should be a transaction to commit. */ 100 126 if (journal->commitSequence != journal->commitRequest) 101 127 { 102 128 TimerRemove(&commitTimer); 103 104 129 JournalCommitTransaction(journal); 105 130 } … … 113 138 ThrSchedule(); /* Will return here when the thread is scheduled again */ 114 139 WaitRemoveFromQueue(&journal->commitWait, &commitWait); 115 140 116 141 /* Get the running transaction, if we timed out, and commit that. Check expires. */ 117 142 if (journal->currTransaction && currTime.seconds >= journal->currTransaction->expires) 118 143 journal->commitRequest=journal->currTransaction->transId; 119 144 } 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 154 int 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); 126 173 127 174 return 0; … … 162 209 return JournalAddHeader(buffer); 163 210 } 211 212 int 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 239 SYMBOL_EXPORT(JournalDestroy); 240 241 void JournalSetUuid(struct Journal* journal, BYTE* uuid) 242 { 243 memcpy(journal->uuid, uuid, 16); 244 } 245 246 SYMBOL_EXPORT(JournalSetUuid); 164 247 165 248 struct Journal* JournalCreate(struct VNode* vNode) … … 177 260 178 261 journal->vNode=vNode; 262 ListRemove(&vNode->next); /* So that SysUnmount can unmount. Is this the right way to do it? */ 179 263 180 264 /* Read the journal superblock. */ 181 265 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 } 182 273 183 274 headerBuf=JournalBlockRead(journal, blockNo); … … 209 300 journal->maxLength=vNode->size/BYTES_PER_SECTOR(vNode->superBlock); 210 301 journal->sectorSize=BYTES_PER_SECTOR(vNode->superBlock); 211 journal->transSequence=1; 302 journal->transSequence=1; /* Check */ 212 303 213 304 if (BeToCpu32(jSb->maxLen) < journal->maxLength) … … 230 321 journal->commitSequence=journal->transSequence-1; 231 322 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); 234 326 journal->free=BeToCpu32(jSb->maxLen)-journal->head; 235 327 328 INIT_LIST_HEAD(&journal->checkpointTrans); 329 INIT_WAITQUEUE_HEAD(&journal->waitUpdates); 330 236 331 ThrStartThread(journal->commitThread); 237 332 333 /* TODO: Wait for it to get started up before continuing */ 334 238 335 return journal; 239 336 }