00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "lfsprocs.h"
00022
00023
00024
00025
00026
00027 #define Dbg (DEBUG_TRACE_LSN_SUP)
00028
00029
#ifdef ALLOC_PRAGMA
00030
#pragma alloc_text(PAGE, LfsFindNextLsn)
00031
#pragma alloc_text(PAGE, LfsLsnFinalOffset)
00032
#endif
00033
00034
00035
VOID
00036 LfsLsnFinalOffset (
00037 IN
PLFCB Lfcb,
00038 IN LSN Lsn,
00039 IN ULONG DataLength,
00040 OUT PLONGLONG FinalOffset
00041 )
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 {
00069 ULONG RemainingPageBytes;
00070 ULONG PageOffset;
00071
00072
PAGED_CODE();
00073
00074
DebugTrace( +1,
Dbg,
"LfsLsnFinalOffset: Entered\n", 0 );
00075
DebugTrace( 0,
Dbg,
"Lfcb -> %08lx\n", Lfcb );
00076
DebugTrace( 0,
Dbg,
"Lsn (Low) -> %08lx\n", Lsn.LowPart );
00077
DebugTrace( 0,
Dbg,
"Lsn (High) -> %08lx\n", Lsn.HighPart );
00078
DebugTrace( 0,
Dbg,
"DataLength -> %08lx\n", DataLength );
00079
00080
00081
00082
00083
00084
00085
00086
LfsTruncateLsnToLogPage( Lfcb, Lsn, FinalOffset );
00087
00088 PageOffset =
LfsLsnToPageOffset( Lfcb, Lsn );
00089
00090 RemainingPageBytes = (ULONG)Lfcb->LogPageSize - PageOffset;
00091
00092 PageOffset -= 1;
00093
00094
00095
00096
00097
00098 DataLength += Lfcb->RecordHeaderLength;
00099
00100
00101
00102
00103
00104
00105
if (DataLength > RemainingPageBytes) {
00106
00107 DataLength -= RemainingPageBytes;
00108
00109 RemainingPageBytes = (ULONG)Lfcb->LogPageDataSize;
00110
00111 PageOffset = (ULONG)Lfcb->LogPageDataOffset - 1;
00112
00113
while (
TRUE) {
00114
00115 BOOLEAN Wrapped;
00116
00117
LfsNextLogPageOffset( Lfcb, *FinalOffset, FinalOffset, &Wrapped );
00118
00119
00120
00121
00122
00123
if (DataLength <= RemainingPageBytes) {
00124
00125
break;
00126 }
00127
00128 DataLength -= RemainingPageBytes;
00129 }
00130 }
00131
00132
00133
00134
00135
00136
00137 *(PULONG)FinalOffset += (DataLength + PageOffset);
00138
00139
DebugTrace( 0,
Dbg,
"FinalOffset (Low) -> %08lx\n", LogPageFileOffset.LowPart );
00140
DebugTrace( 0,
Dbg,
"FinalOffset (High) -> %08lx\n", LogPageFileOffset.HighPart );
00141
DebugTrace( -1,
Dbg,
"LfsLsnFinalOffset: Exit\n", 0 );
00142
00143
return;
00144 }
00145
00146
00147 BOOLEAN
00148 LfsFindNextLsn (
00149 IN
PLFCB Lfcb,
00150 IN
PLFS_RECORD_HEADER RecordHeader,
00151 OUT PLSN Lsn
00152 )
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 {
00178 BOOLEAN FoundNextLsn;
00179
00180 LONGLONG LsnOffset;
00181 LONGLONG EndOfLogRecord;
00182 LONGLONG LogHeaderOffset;
00183
00184 LONGLONG SequenceNumber;
00185
00186
PLFS_RECORD_PAGE_HEADER LogRecordPage;
00187
PBCB LogRecordPageBcb;
00188 BOOLEAN UsaError;
00189
00190
PAGED_CODE();
00191
00192
DebugTrace( +1,
Dbg,
"LfsFindNextLsn: Entered\n", 0 );
00193
DebugTrace( 0,
Dbg,
"Lfcb -> %08lx\n", Lfcb );
00194
DebugTrace( 0,
Dbg,
"Record Header -> %08lx\n", RecordHeader );
00195
00196 LogRecordPageBcb =
NULL;
00197 FoundNextLsn =
FALSE;
00198
00199
00200
00201
00202
00203
try {
00204
00205
00206
00207
00208
00209
00210 LsnOffset =
LfsLsnToFileOffset( Lfcb, RecordHeader->ThisLsn );
00211
00212
LfsLsnFinalOffset( Lfcb,
00213 RecordHeader->ThisLsn,
00214 RecordHeader->ClientDataLength,
00215 &EndOfLogRecord );
00216
00217
LfsTruncateOffsetToLogPage( Lfcb, EndOfLogRecord, &LogHeaderOffset );
00218
00219
00220
00221
00222
00223 SequenceNumber =
LfsLsnToSeqNumber( Lfcb, RecordHeader->ThisLsn );
00224
00225
00226
00227
00228
00229
if ( EndOfLogRecord <= LsnOffset ) {
00230
00231 SequenceNumber = SequenceNumber + 1;
00232 }
00233
00234
00235
00236
00237
00238
LfsPinOrMapData( Lfcb,
00239 LogHeaderOffset,
00240 (ULONG)Lfcb->LogPageSize,
00241
FALSE,
00242
FALSE,
00243
FALSE,
00244 &UsaError,
00245 (PVOID *)&LogRecordPage,
00246 &LogRecordPageBcb );
00247
00248
00249
00250
00251
00252
00253
00254
00255
if ( RecordHeader->ThisLsn.QuadPart == LogRecordPage->Copy.LastLsn.QuadPart ) {
00256
00257 BOOLEAN Wrapped;
00258
00259
LfsNextLogPageOffset( Lfcb,
00260 LogHeaderOffset,
00261 &LogHeaderOffset,
00262 &Wrapped );
00263
00264 LsnOffset = LogHeaderOffset + Lfcb->LogPageDataOffset;
00265
00266
00267
00268
00269
00270
if (Wrapped) {
00271
00272 SequenceNumber = SequenceNumber + 1;
00273 }
00274
00275 }
else {
00276
00277
LiQuadAlign( EndOfLogRecord, &LsnOffset );
00278 }
00279
00280
00281
00282
00283
00284 Lsn->QuadPart =
LfsFileOffsetToLsn( Lfcb, LsnOffset, SequenceNumber );
00285
00286
00287
00288
00289
00290
00291
if (
LfsIsLsnInFile( Lfcb, *Lsn )) {
00292
00293 FoundNextLsn =
TRUE;
00294 }
00295
00296 } finally {
00297
00298
DebugUnwind(
LfsFindNextLsn );
00299
00300
00301
00302
00303
00304
if (LogRecordPageBcb !=
NULL) {
00305
00306
CcUnpinData( LogRecordPageBcb );
00307 }
00308
00309
DebugTrace( 0,
Dbg,
"Lsn (Low) -> %08lx\n", Lsn->LowPart );
00310
DebugTrace( 0,
Dbg,
"Lsn (High) -> %08lx\n", Lsn->HighPart );
00311
DebugTrace( -1,
Dbg,
"LfsFindNextLsn: Exit -> %08x\n", FoundNextLsn );
00312 }
00313
00314
return FoundNextLsn;
00315 }
00316