00124 :
00125
00126 This routine
is called to verify that we may write
this log record into
the
00127 log
file. We want to always leave room
for each transaction to abort.
00128
00129 We determine how much space
the current log record will take and
the
00130 worst
case for its undo operation. If
this space
is available we
00131 update
the corresponding values in
the Lfcb and Lch
for bookkeeping.
00132 Otherwise we raise a status indicating that
the log
file is full.
00133
00134 The disk usage
is different
for the packed and unpacked cases. Make
the
00135 following adjustments after finding
the total available and amount still
00136 remaining on
the last active page,
00137
00138 Packed Case:
00139
00140
Size needed
for log record
is data size plus header size.
00141
00142 Undo requirement
is the undo data size plus
the header size.
00143 We have already taken into account
the end of
the pages
00144 except
for the current page.
00145
00146 Add
the log record size to
the undo requirement to get
the
00147 log
file usage.
Compare this number with
the actual available
00148 space (Available - CommittedUndo). If
the space
is not
00149 available, then raise LOG_FILE_FULL. Must take into account
00150 any unused bytes at
the end of
the current page.
00151
00152 Unpacked Case:
00153
00154
Size needed
is initially header size plus data size.
00155
00156 If
the log record can'
t begin on
the current page then
00157 add
the bytes being thrown away to
the log record size.
00158
00159 If
the page
is being forced to disk then add any remaining
00160 bytes on
the last page. To
the bytes being used.
00161
00162 Undo requirement
is twice
the sum of
the header size and
00163 undo size. We
double the requested size since
the log
00164 record will always fit on a page. This can be a
00165 positive or negative number.
00166
00167 Add
the log record usage to
the undo usage to get
the log
file
00168 usage.
Compare this number with
the actual available
00169 space (Available - CommittedUndo). If
the space
is not
00170 available, then raise LOG_FILE_FULL.
00171
00172 Arguments:
00173
00174 Lfcb - Lfcb
for this log
file.
00175
00176 Lch - Client handle
00177
00178 RemainingLogBytes - Number of bytes
for the current log record
00179
00180 UndoRequirement - User's requirement
for the undo record.
00181
00182 ForceToDisk - Indicates
if this log record will be flushed to disk.
00183
00184 Return Value:
00185
00186 BOOLEAN - Advisory, indicates that there
is less than 1/4 of
the log
file available.
00187
00188 --*/
00189
00190 {
00191 ULONG CurrentLogRecordSize;
00192 ULONG LogRecordStart;
00193 ULONG TailBytes;
00194
00195 LONGLONG CurrentAvailSpace;
00196 ULONG CurrentPageBytes;
00197
00198 LONGLONG LogFileUsage;
00199
00200
PAGED_CODE();
00201
00202
DebugTrace( +1, Dbg,
"LfsVerifyLogSpaceAvail: Entered\n", 0 );
00203
DebugTrace( 0, Dbg,
"Lfcb -> %08x\n", Lfcb );
00204
DebugTrace( 0, Dbg,
"Lch -> %08lx\n", Lch );
00205
DebugTrace( 0, Dbg,
"RemainingLogBytes -> %08lx\n", RemainingLogBytes );
00206
DebugTrace( 0, Dbg,
"UndoRequirement -> %08lx\n", UndoRequirement );
00207
DebugTrace( 0, Dbg,
"ForceToDisk -> %04x\n", ForceToDisk );
00208
00209
00210
00211
00212
00213
LfsCurrentAvailSpace( Lfcb,
00214 &CurrentAvailSpace,
00215 &CurrentPageBytes );
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 CurrentLogRecordSize = RemainingLogBytes + Lfcb->RecordHeaderLength;
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
if (
FlagOn( Lfcb->Flags, LFCB_PACK_LOG )) {
00242
00243
if (CurrentPageBytes != 0
00244 && CurrentLogRecordSize < CurrentPageBytes
00245 && (CurrentPageBytes - CurrentLogRecordSize) < Lfcb->RecordHeaderLength) {
00246
00247 CurrentLogRecordSize += (CurrentPageBytes - CurrentLogRecordSize);
00248 }
00249
00250
00251
00252
00253
00254
00255 }
else {
00256
00257
00258
00259
00260
00261
00262
if (CurrentPageBytes != 0) {
00263
00264
00265
00266
00267
00268
00269
if ((CurrentPageBytes != (ULONG)Lfcb->LogPageDataSize)
00270 && (CurrentLogRecordSize > CurrentPageBytes)) {
00271
00272 CurrentLogRecordSize += CurrentPageBytes;
00273
00274
00275
00276
00277
00278
00279 LogRecordStart = 0;
00280
00281
00282
00283
00284
00285
00286 }
else {
00287
00288 LogRecordStart = (ULONG)Lfcb->LogPageDataSize - CurrentPageBytes;
00289 }
00290
00291
00292
00293
00294
00295
00296 }
else {
00297
00298 LogRecordStart = 0;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
if (ForceToDisk) {
00308
00309
00310
00311
00312
00313
00314
00315 TailBytes = RemainingLogBytes + Lfcb->RecordHeaderLength + LogRecordStart;
00316
00317
while (TailBytes > (ULONG)Lfcb->LogPageDataSize) {
00318
00319 TailBytes -= (ULONG)Lfcb->LogPageDataSize;
00320 }
00321
00322 TailBytes = (ULONG)Lfcb->LogPageDataSize - TailBytes;
00323
00324 CurrentLogRecordSize += TailBytes;
00325 }
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
if (UndoRequirement != 0) {
00343
00344
if (!
FlagOn( Lfcb->Flags, LFCB_PACK_LOG )) {
00345
00346 UndoRequirement *= 2;
00347 }
00348
00349
if (UndoRequirement < 0) {
00350
00351 UndoRequirement -= (2 * Lfcb->RecordHeaderLength);
00352 }
else {
00353
00354 UndoRequirement += (2 * Lfcb->RecordHeaderLength);
00355 }
00356 }
00357
00358
00359
00360
00361
00362
00363 LogFileUsage = ((LONG) CurrentLogRecordSize) + UndoRequirement;
00364
00365
00366
00367
00368
00369
00370 CurrentAvailSpace = CurrentAvailSpace - Lfcb->TotalUndoCommitment;
00371
00372
00373
00374
00375
00376
00377
#ifdef LFS_RAISE
00378
if (LfsRaiseFull) {
00379
00380 LfsRaiseFull =
FALSE;
00381
DebugTrace( -1, Dbg,
"LfsVerifyLogSpaceAvail: About to raise\n", 0 );
00382
ExRaiseStatus( STATUS_LOG_FILE_FULL );
00383 }
00384
#endif
00385
00386
if (LogFileUsage > CurrentAvailSpace) {
00387
00388
DebugTrace( -1, Dbg,
"LfsVerifyLogSpaceAvail: About to raise\n", 0 );
00389
ExRaiseStatus( STATUS_LOG_FILE_FULL );
00390 }
00391
00392 Lfcb->TotalUndoCommitment = Lfcb->TotalUndoCommitment + UndoRequirement;
00393
00394 Lch->ClientUndoCommitment = Lch->ClientUndoCommitment + UndoRequirement;
00395
00396
DebugTrace( -1, Dbg,
"LfsVerifyLogSpaceAvail: Exit\n", 0 );
00397
00398
00399
00400
00401
00402
if ((CurrentAvailSpace - LogFileUsage) < (Lfcb->TotalAvailable >> 2)) {
00403
00404
return TRUE;
00405 }
00406
00407
return FALSE;
00408 }