| | 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 | |
| | 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); |