| | 100 | |
| | 101 | /* We get a copy of curr, newHead, that points at the journal block |
| | 102 | * to write to. The real write of metadata to the disk takes place |
| | 103 | * in the checkpoint. |
| | 104 | */ |
| | 105 | |
| | 106 | if (!firstTag) |
| | 107 | tagFlags |= JOURN_FLAG_SAME_UUID; |
| | 108 | |
| | 109 | tag=(struct JournalBlockTag*)tagPointer; |
| | 110 | tag->blockNum=CpuToBe32(JournHeadToBuffer(curr)->blockNum); |
| | 111 | tag->flags=CpuToBe32(tagFlags); |
| | 112 | |
| | 113 | tagPointer+=sizeof(struct JournalBlockTag); |
| | 114 | spaceLeft-=sizeof(struct JournalBlockTag); |
| | 115 | |
| | 116 | if (firstTag) |
| | 117 | { |
| | 118 | memcpy(tagPointer, journal->uuid, 16); |
| | 119 | tagPointer+=16; |
| | 120 | spaceLeft-=16; |
| | 121 | firstTag=0; |
| | 122 | } |
| | 123 | |
| | 124 | buffers[bufIndex++]=JournHeadToBuffer(newHead); |
| | 125 | |
| | 126 | /* Are we at the end of the list, or has the descriptor block run out of |
| | 127 | * space? |
| | 128 | */ |
| | 129 | if (bufIndex == 64 || curr2->next.next == &commitTrans->metaDataList || |
| | 130 | spaceLeft < sizeof(struct JournalBlockTag)+16) |
| | 131 | { |
| | 132 | int i; |
| | 133 | |
| | 134 | KePrint("Submitting %d buffers\n", bufIndex); |
| | 135 | tag->flags|=CpuToBe32(JOURN_FLAG_LAST_TAG); |
| | 136 | |
| | 137 | JournalUnlock(journal); |
| | 138 | |
| | 139 | for (i=0; i<bufIndex; i++) |
| | 140 | { |
| | 141 | BlockWrite(buffers[i]->device, buffers[i]); |
| | 142 | } |
| | 143 | |
| | 144 | JournalLock(journal); |
| | 145 | } |
| 100 | | SYMBOL_EXPORT(JournalWaitCommit); |
| | 152 | int JournalWaitForIO(struct Journal* journal, struct JournalTrans* commitTrans) |
| | 153 | { |
| | 154 | struct JournalHead* curr, *curr2; |
| | 155 | struct JournalHead* shadow=ListEntry(commitTrans->shadowList.next, struct JournalHead, next), *shadow2; |
| | 156 | |
| | 157 | /* Go through the journal I/O list. */ |
| | 158 | ListForEachEntrySafe(curr, curr2, &commitTrans->ioList, next) |
| | 159 | { |
| | 160 | struct Buffer* buffer; |
| | 161 | |
| | 162 | buffer=JournHeadToBuffer(curr); |
| | 163 | WaitForBuffer(buffer); |
| | 164 | JournalUnfileBuffer(curr); |
| | 165 | |
| | 166 | /* Get the corresponding shadow buffer, and file that to a checkpoint list. */ |
| | 167 | shadow2=ListEntry(shadow->next.next, struct JournalHead, next); |
| | 168 | KePrint("Filing %u\n", JournHeadToBuffer(shadow)->blockNum); |
| | 169 | JournalFileBuffer(shadow, commitTrans, JOURN_FORGET); |
| | 170 | WakeUp(&shadow->wait); |
| | 171 | shadow=shadow2; |
| | 172 | } |
| | 173 | |
| | 174 | return 0; |
| | 175 | } |
| | 176 | |
| | 177 | int JournalWriteCommitRecord(struct Journal* journal, struct JournalTrans* commitTrans) |
| | 178 | { |
| | 179 | struct JournalHead* head; |
| | 180 | struct Buffer* buffer; |
| | 181 | DWORD i; |
| | 182 | |
| | 183 | head=JournalGetDescriptorBuffer(journal); |
| | 184 | buffer=JournHeadToBuffer(head); |
| | 185 | |
| | 186 | for (i=0; i<journal->sectorSize; i+=512) |
| | 187 | { |
| | 188 | struct JournalHeader* header=(struct JournalHeader*)(buffer->data+i); |
| | 189 | header->magic=CpuToBe32(JFS_MAGIC); |
| | 190 | header->blockType=CpuToBe32(JFS_COMMIT_BLOCK); |
| | 191 | header->sequence=CpuToBe32(commitTrans->transId); |
| | 192 | } |
| | 193 | |
| | 194 | JournalUnlock(journal); |
| | 195 | |
| | 196 | BlockWrite(buffer->device, buffer); |
| | 197 | WaitForBuffer(buffer); |
| | 198 | BufferRelease(buffer); |
| | 199 | |
| | 200 | return 0; |
| | 201 | } |
| 129 | | |
| 130 | | JournalUnlock(journal); |
| | 237 | |
| | 238 | /* Make sure the data is written to disk, and the metadata is written to the |
| | 239 | * journal. |
| | 240 | */ |
| | 241 | JournalWaitForIO(journal, commitTrans); |
| | 242 | |
| | 243 | /* Make sure the descriptor records are written to disk */ |
| | 244 | |
| | 245 | ListAddTail(&commitTrans->next, &journal->checkpointTrans); |
| | 246 | |
| | 247 | /* Write the commit record. */ |
| | 248 | JournalWriteCommitRecord(journal, commitTrans); |
| | 249 | |
| | 250 | /* TEST: Checkpoint the transaction. */ |
| | 251 | JournalCheckpoint(journal); |
| | 252 | |