00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "lfsprocs.h"
00023
00024
00025
00026
00027
00028 #define Dbg (DEBUG_TRACE_WRITE)
00029
00030
#ifdef ALLOC_PRAGMA
00031
#pragma alloc_text(PAGE, LfsCheckWriteRange)
00032
#pragma alloc_text(PAGE, LfsFlushToLsn)
00033
#pragma alloc_text(PAGE, LfsForceWrite)
00034
#pragma alloc_text(PAGE, LfsWrite)
00035
#endif
00036
00037
00038 BOOLEAN
00039 LfsWrite (
00040 IN LFS_LOG_HANDLE LogHandle,
00041 IN ULONG NumberOfWriteEntries,
00042 IN
PLFS_WRITE_ENTRY WriteEntries,
00043 IN LFS_RECORD_TYPE RecordType,
00044 IN TRANSACTION_ID *TransactionId OPTIONAL,
00045 IN LSN UndoNextLsn,
00046 IN LSN PreviousLsn,
00047 IN LONG UndoRequirement,
00048 OUT PLSN Lsn
00049 )
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 {
00089
volatile NTSTATUS Status = STATUS_SUCCESS;
00090
00091 BOOLEAN LogFileFull =
FALSE;
00092
PLCH Lch;
00093
00094
PLFCB Lfcb;
00095
00096
PAGED_CODE();
00097
00098
DebugTrace( +1,
Dbg,
"LfsWrite: Entered\n", 0 );
00099
DebugTrace( 0,
Dbg,
"Log Handle -> %08lx\n", LogHandle );
00100
DebugTrace( 0,
Dbg,
"NumberOfWriteEntries -> %08lx\n", NumberOfWriteEntries );
00101
DebugTrace( 0,
Dbg,
"WriteEntries -> %08lx\n", WriteEntries );
00102
DebugTrace( 0,
Dbg,
"Record Type -> %08lx\n", RecordType );
00103
DebugTrace( 0,
Dbg,
"Transaction Id -> %08lx\n", TransactionId );
00104
DebugTrace( 0,
Dbg,
"UndoNextLsn (Low) -> %08lx\n", UndoNextLsn.LowPart );
00105
DebugTrace( 0,
Dbg,
"UndoNextLsn (High) -> %08lx\n", UndoNextLsn.HighPart );
00106
DebugTrace( 0,
Dbg,
"PreviousLsn (Low) -> %08lx\n", PreviousLsn.LowPart );
00107
DebugTrace( 0,
Dbg,
"PreviousLsn (High) -> %08lx\n", PreviousLsn.HighPart );
00108
00109 Lch = (
PLCH) LogHandle;
00110
00111
00112
00113
00114
00115
LfsValidateLch( Lch );
00116
00117
00118
00119
00120
00121
try {
00122
00123
00124
00125
00126
00127
try {
00128
00129
00130
00131
00132
00133
LfsAcquireLch( Lch );
00134 Lfcb = Lch->
Lfcb;
00135
00136
00137
00138
00139
00140
if (Lfcb ==
NULL) {
00141
00142
ExRaiseStatus( STATUS_ACCESS_DENIED );
00143 }
00144
00145
00146
00147
00148
00149
LfsValidateClientId( Lfcb, Lch );
00150
00151
00152
00153
00154
00155 LogFileFull =
LfsWriteLogRecordIntoLogPage( Lfcb,
00156 Lch,
00157 NumberOfWriteEntries,
00158 WriteEntries,
00159 RecordType,
00160 TransactionId,
00161 UndoNextLsn,
00162 PreviousLsn,
00163 UndoRequirement,
00164
FALSE,
00165 Lsn );
00166
00167 } finally {
00168
00169
DebugUnwind(
LfsWrite );
00170
00171
00172
00173
00174
00175
LfsReleaseLch( Lch );
00176
00177
DebugTrace( 0,
Dbg,
"Lsn (Low) -> %08lx\n", Lsn->LowPart );
00178
DebugTrace( 0,
Dbg,
"Lsn (High) -> %08lx\n", Lsn->HighPart );
00179
DebugTrace( -1,
Dbg,
"LfsWrite: Exit\n", 0 );
00180 }
00181
00182 } except (
LfsExceptionFilter( GetExceptionInformation() )) {
00183
00184
Status = GetExceptionCode();
00185 }
00186
00187
if (
Status != STATUS_SUCCESS) {
00188
00189
ExRaiseStatus(
Status );
00190 }
00191
00192
return LogFileFull;
00193 }
00194
00195
00196 BOOLEAN
00197 LfsForceWrite (
00198 IN LFS_LOG_HANDLE LogHandle,
00199 IN ULONG NumberOfWriteEntries,
00200 IN
PLFS_WRITE_ENTRY WriteEntries,
00201 IN LFS_RECORD_TYPE RecordType,
00202 IN TRANSACTION_ID *TransactionId,
00203 IN LSN UndoNextLsn,
00204 IN LSN PreviousLsn,
00205 IN LONG UndoRequirement,
00206 OUT PLSN Lsn
00207 )
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 {
00245
volatile NTSTATUS Status = STATUS_SUCCESS;
00246
00247
PLCH Lch;
00248
00249
PLFCB Lfcb;
00250 BOOLEAN LogFileFull =
FALSE;
00251
00252
PAGED_CODE();
00253
00254
DebugTrace( +1,
Dbg,
"LfsForceWrite: Entered\n", 0 );
00255
DebugTrace( 0,
Dbg,
"Log Handle -> %08lx\n", LogHandle );
00256
DebugTrace( 0,
Dbg,
"NumberOfWriteEntries -> %08lx\n", NumberOfWriteEntries );
00257
DebugTrace( 0,
Dbg,
"WriteEntries -> %08lx\n", WriteEntries );
00258
DebugTrace( 0,
Dbg,
"Record Type -> %08lx\n", RecordType );
00259
DebugTrace( 0,
Dbg,
"Transaction Id -> %08lx\n", TransactionId );
00260
DebugTrace( 0,
Dbg,
"UndoNextLsn (Low) -> %08lx\n", UndoNextLsn.LowPart );
00261
DebugTrace( 0,
Dbg,
"UndoNextLsn (High) -> %08lx\n", UndoNextLsn.HighPart );
00262
DebugTrace( 0,
Dbg,
"PreviousLsn (Low) -> %08lx\n", PreviousLsn.LowPart );
00263
DebugTrace( 0,
Dbg,
"PreviousLsn (High) -> %08lx\n", PreviousLsn.HighPart );
00264
00265 Lch = (
PLCH) LogHandle;
00266
00267
00268
00269
00270
00271
LfsValidateLch( Lch );
00272
00273
00274
00275
00276
00277
try {
00278
00279
00280
00281
00282
00283
try {
00284
00285
00286
00287
00288
00289
LfsAcquireLch( Lch );
00290 Lfcb = Lch->
Lfcb;
00291
00292
00293
00294
00295
00296
if (Lfcb ==
NULL) {
00297
00298
ExRaiseStatus( STATUS_ACCESS_DENIED );
00299 }
00300
00301
00302
00303
00304
00305
LfsValidateClientId( Lfcb, Lch );
00306
00307
00308
00309
00310
00311 LogFileFull =
LfsWriteLogRecordIntoLogPage( Lfcb,
00312 Lch,
00313 NumberOfWriteEntries,
00314 WriteEntries,
00315 RecordType,
00316 TransactionId,
00317 UndoNextLsn,
00318 PreviousLsn,
00319 UndoRequirement,
00320
TRUE,
00321 Lsn );
00322
00323
00324
00325
00326
00327
00328
LfsFlushToLsnPriv( Lfcb, *Lsn );
00329
00330 } finally {
00331
00332
DebugUnwind(
LfsForceWrite );
00333
00334
00335
00336
00337
00338
LfsReleaseLch( Lch );
00339
00340
DebugTrace( 0,
Dbg,
"Lsn (Low) -> %08lx\n", Lsn->LowPart );
00341
DebugTrace( 0,
Dbg,
"Lsn (High) -> %08lx\n", Lsn->HighPart );
00342
DebugTrace( -1,
Dbg,
"LfsForceWrite: Exit\n", 0 );
00343 }
00344
00345 } except (
LfsExceptionFilter( GetExceptionInformation() )) {
00346
00347
Status = GetExceptionCode();
00348 }
00349
00350
if (
Status != STATUS_SUCCESS) {
00351
00352
ExRaiseStatus(
Status );
00353 }
00354
00355
return LogFileFull;
00356 }
00357
00358
00359
VOID
00360 LfsFlushToLsn (
00361 IN LFS_LOG_HANDLE LogHandle,
00362 IN LSN Lsn
00363 )
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 {
00390
volatile NTSTATUS Status = STATUS_SUCCESS;
00391
00392
PLCH Lch;
00393
00394
PLFCB Lfcb;
00395
00396
PAGED_CODE();
00397
00398
DebugTrace( +1,
Dbg,
"LfsFlushToLsn: Entered\n", 0 );
00399
DebugTrace( 0,
Dbg,
"Log Handle -> %08lx\n", LogHandle );
00400
DebugTrace( 0,
Dbg,
"Lsn (Low) -> %08lx\n", Lsn.LowPart );
00401
DebugTrace( 0,
Dbg,
"Lsn (High) -> %08lx\n", Lsn.HighPart );
00402
00403 Lch = (
PLCH) LogHandle;
00404
00405
00406
00407
00408
00409
LfsValidateLch( Lch );
00410
00411
00412
00413
00414
00415
try {
00416
00417
00418
00419
00420
00421
try {
00422
00423
00424
00425
00426
00427
LfsAcquireLch( Lch );
00428 Lfcb = Lch->
Lfcb;
00429
00430
00431
00432
00433
00434
if (Lfcb !=
NULL) {
00435
00436
00437
00438
00439
00440
LfsValidateClientId( Lfcb, Lch );
00441
00442
00443
00444
00445
00446
LfsFlushToLsnPriv( Lfcb, Lsn );
00447 }
00448
00449 } finally {
00450
00451
DebugUnwind(
LfsFlushToLsn );
00452
00453
00454
00455
00456
00457
LfsReleaseLch( Lch );
00458
00459
DebugTrace( -1,
Dbg,
"LfsFlushToLsn: Exit\n", 0 );
00460 }
00461
00462 } except (
LfsExceptionFilter( GetExceptionInformation() )) {
00463
00464
Status = GetExceptionCode();
00465 }
00466
00467
if (
Status != STATUS_SUCCESS) {
00468
00469
ExRaiseStatus(
Status );
00470 }
00471
00472
return;
00473 }
00474
00475
00476
VOID
00477 LfsCheckWriteRange (
00478 IN
PLFS_WRITE_DATA WriteData,
00479 IN OUT PLONGLONG FlushOffset,
00480 IN OUT PULONG FlushLength
00481 )
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 {
00513 PLIST_ENTRY Links;
00514
PLFCB Lfcb;
00515
PLFCB NextLfcb;
00516
PAGED_CODE();
00517
00518
00519
00520
00521
00522 Lfcb = WriteData->Lfcb;
00523
00524
00525
00526
00527
00528
if (
PAGE_SIZE != Lfcb->
SystemPageSize) {
00529
00530
00531
00532
00533
00534
if (*FlushOffset < WriteData->FileOffset) {
00535
00536 *FlushLength -= (ULONG) (WriteData->FileOffset - *FlushOffset);
00537 *FlushOffset = WriteData->FileOffset;
00538 }
00539
00540
00541
00542
00543
00544
if (*FlushOffset + *FlushLength > WriteData->FileOffset + WriteData->Length) {
00545
00546 *FlushLength = (ULONG) (WriteData->FileOffset + WriteData->Length - *FlushOffset);
00547 }
00548
00549
00550
00551
00552
00553
if ((Lfcb->
PageToDirty !=
NULL) &&
00554 (*FlushLength + *FlushOffset == Lfcb->
PageToDirty->
FileOffset)) {
00555
00556 *((PULONG) (Lfcb->
PageToDirty->
PageHeader)) =
LFS_SIGNATURE_RECORD_PAGE_ULONG;
00557 }
00558 }
00559
00560
return;
00561 }
00562
00563