Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

verfysup.c File Reference

#include "lfsprocs.h"

Go to the source code of this file.

Functions

VOID LfsCurrentAvailSpace (IN PLFCB Lfcb, OUT PLONGLONG CurrentAvailSpace, OUT PULONG CurrentPageBytes)
BOOLEAN LfsVerifyLogSpaceAvail (IN PLFCB Lfcb, IN PLCH Lch, IN ULONG RemainingLogBytes, IN LONG UndoRequirement, IN BOOLEAN ForceToDisk)
VOID LfsFindCurrentAvail (IN PLFCB Lfcb)


Function Documentation

VOID LfsCurrentAvailSpace IN PLFCB  Lfcb,
OUT PLONGLONG  CurrentAvailSpace,
OUT PULONG  CurrentPageBytes
 

Definition at line 36 of file lfs/verfysup.c.

References _LBCB::BufferOffset, Dbg, DebugTrace, FlagOn, LBCB_FLUSH_COPY, LBCB_NOT_EMPTY, _LBCB::LbcbFlags, and PAGED_CODE.

Referenced by LfsFlushToLsnPriv(), LfsReadLogFileInformation(), and LfsVerifyLogSpaceAvail().

00044 : 00045 00046 This routine is called to determine the available log space in the log file. 00047 It returns the total number of free bytes and the number available on the 00048 active page if present. The total free bytes will reflect all of the empty 00049 pages as well as the number in the active page. 00050 00051 Arguments: 00052 00053 Lfcb - Lfcb for this log file. 00054 00055 CurrentAvailSpace - This is the number of bytes available for log 00056 records. 00057 00058 CurrentPageBytes - This is the number of bytes remaining on the 00059 current log page. 00060 00061 Return Value: 00062 00063 None. 00064 00065 --*/ 00066 00067 { 00068 *CurrentPageBytes = 0; 00069 00070 PAGED_CODE(); 00071 00072 DebugTrace( +1, Dbg, "LfsCurrentAvailSpace: Entered\n", 0 ); 00073 00074 // 00075 // Get the total number from the Lfcb. 00076 // 00077 00078 *CurrentAvailSpace = Lfcb->CurrentAvailable; 00079 00080 // 00081 // We now look to see if there are any bytes available on the Lbcb in 00082 // the active queue. We can add this to the bytes available in the 00083 // log pages and also give this back to the caller. 00084 // 00085 00086 if (!IsListEmpty( &Lfcb->LbcbActive )) { 00087 00088 PLBCB ThisLbcb; 00089 00090 ThisLbcb = CONTAINING_RECORD( Lfcb->LbcbActive.Flink, 00091 LBCB, 00092 ActiveLinks ); 00093 00094 // 00095 // If the page is not empty or the page is empty but this is a 00096 // restart page then add the remaining bytes on this page. 00097 // 00098 00099 if (FlagOn( ThisLbcb->LbcbFlags, LBCB_NOT_EMPTY | LBCB_FLUSH_COPY )) { 00100 00101 *CurrentPageBytes = (ULONG)Lfcb->LogPageSize - (ULONG)ThisLbcb->BufferOffset; 00102 00103 *CurrentAvailSpace = *CurrentAvailSpace + *CurrentPageBytes; //**** xxAdd( *CurrentAvailSpace, xxFromUlong( *CurrentPageBytes )); 00104 } 00105 } 00106 00107 DebugTrace( +1, Dbg, "LfsCurrentAvailSpace: Exit\n", 0 ); 00108 00109 return; 00110 }

VOID LfsFindCurrentAvail IN PLFCB  Lfcb  ) 
 

Definition at line 412 of file lfs/verfysup.c.

References Dbg, DebugTrace, FlagOn, LFCB_NO_LAST_LSN, LFCB_NO_OLDEST_LSN, LFCB_REUSE_TAIL, LfsTruncateOffsetToLogPage, and PAGED_CODE.

Referenced by LfsRestartLogFile(), LfsSetBaseLsnPriv(), and LfsUpdateLfcbFromRestart().

00418 : 00419 00420 This routine is called to calculate the number of bytes available for log 00421 records which are in completely empty log record pages. It ignores any 00422 partial pages in the active work queue and ignores any page which is 00423 going to be reused. 00424 00425 Arguments: 00426 00427 Lfcb - Lfcb for this log file. 00428 00429 Return Value: 00430 00431 None. 00432 00433 --*/ 00434 00435 { 00436 LONGLONG OldestPageOffset; 00437 LONGLONG NextFreePageOffset; 00438 LONGLONG FreeBytes; 00439 00440 PAGED_CODE(); 00441 00442 DebugTrace( +1, Dbg, "LfsFindCurrentAvail: Entered\n", 0 ); 00443 DebugTrace( 0, Dbg, "Lfcb -> %08x\n", Lfcb ); 00444 00445 // 00446 // If there is a last lsn in the restart area then we know 00447 // that we will have to compute the free range. 00448 // 00449 00450 if (!FlagOn( Lfcb->Flags, LFCB_NO_LAST_LSN )) { 00451 00452 // 00453 // If there is no oldest Lsn then start at the 00454 // first page of the file. 00455 // 00456 00457 if (FlagOn( Lfcb->Flags, LFCB_NO_OLDEST_LSN )) { 00458 00459 OldestPageOffset = Lfcb->FirstLogPage; 00460 00461 } else { 00462 00463 LfsTruncateOffsetToLogPage( Lfcb, 00464 Lfcb->OldestLsnOffset, 00465 &OldestPageOffset ); 00466 } 00467 00468 // 00469 // We will use the next log page offset to compute the 00470 // next free page. If we are going to reuse this page 00471 // go to the next page, if we are at the first page then 00472 // use the end of the file. 00473 // 00474 00475 if (FlagOn( Lfcb->Flags, LFCB_REUSE_TAIL )) { 00476 00477 NextFreePageOffset = Lfcb->NextLogPage + Lfcb->LogPageSize; //**** xxAdd( Lfcb->NextLogPage, Lfcb->LogPageSize ); 00478 00479 } else if ( Lfcb->NextLogPage == Lfcb->FirstLogPage ) { //**** xxEql( Lfcb->NextLogPage, Lfcb->FirstLogPage ) 00480 00481 NextFreePageOffset = Lfcb->FileSize; 00482 00483 } else { 00484 00485 NextFreePageOffset = Lfcb->NextLogPage; 00486 } 00487 00488 // 00489 // If the two offsets are the same then there is no available space. 00490 // 00491 00492 if ( OldestPageOffset == NextFreePageOffset ) { //**** xxEql( OldestPageOffset, NextFreePageOffset ) 00493 00494 Lfcb->CurrentAvailable = 0; 00495 00496 } else { 00497 00498 // 00499 // If the free offset follows the oldest offset then subtract 00500 // this range from the total available pages. 00501 // 00502 00503 if ( OldestPageOffset < NextFreePageOffset ) { //**** xxLtr( OldestPageOffset, NextFreePageOffset ) 00504 00505 FreeBytes = Lfcb->TotalAvailInPages - ( NextFreePageOffset - OldestPageOffset ); //**** xxSub( Lfcb->TotalAvailInPages, xxSub( NextFreePageOffset, OldestPageOffset )); 00506 00507 } else { 00508 00509 FreeBytes = OldestPageOffset - NextFreePageOffset; //**** xxSub( OldestPageOffset, NextFreePageOffset ); 00510 } 00511 00512 // 00513 // We now have the total bytes in the pages available. We 00514 // now have to subtract the size of the page header to get 00515 // the total available bytes. 00516 // 00517 // We will convert the bytes to pages and then multiple 00518 // by the data size of each page. 00519 // 00520 00521 FreeBytes = Int64ShrlMod32(((ULONGLONG)(FreeBytes)), Lfcb->LogPageShift); 00522 00523 Lfcb->CurrentAvailable = FreeBytes * (ULONG)Lfcb->ReservedLogPageSize; //**** xxXMul( FreeBytes, Lfcb->ReservedLogPageSize.LowPart ); 00524 } 00525 00526 // 00527 // Otherwise the entire file is available. 00528 // 00529 00530 } else { 00531 00532 Lfcb->CurrentAvailable = Lfcb->MaxCurrentAvail; 00533 } 00534 00535 DebugTrace( -1, Dbg, "LfsFindCurrentAvail: Exit\n", 0 ); 00536 00537 return; 00538 } }

BOOLEAN LfsVerifyLogSpaceAvail IN PLFCB  Lfcb,
IN PLCH  Lch,
IN ULONG  RemainingLogBytes,
IN LONG  UndoRequirement,
IN BOOLEAN  ForceToDisk
 

Definition at line 114 of file lfs/verfysup.c.

References Dbg, DebugTrace, ExRaiseStatus(), FALSE, FlagOn, LFCB_PACK_LOG, LfsCurrentAvailSpace(), PAGED_CODE, and TRUE.

Referenced by LfsWriteLogRecordIntoLogPage().

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 // Start by collecting the current data on the file. 00211 // 00212 00213 LfsCurrentAvailSpace( Lfcb, 00214 &CurrentAvailSpace, 00215 &CurrentPageBytes ); 00216 00217 // 00218 // We compute the amount of space needed for the current log record by 00219 // adding up the following: 00220 // 00221 // Space at end of current log page which won't be used. 00222 // Size of header for log record. 00223 // Size of client data in log record. 00224 // Size of wasted portion of log page if this is forced to disk. 00225 // 00226 00227 // 00228 // Start with the size of the header and the client data. 00229 // 00230 00231 CurrentLogRecordSize = RemainingLogBytes + Lfcb->RecordHeaderLength; 00232 00233 // 00234 // If the log is packed and there are bytes on the current page we need 00235 // to take into account any bytes at the end of the page which won't 00236 // be used. This will happen if the log record spills into the end of 00237 // the log page but doesn't use up the page. If the remaining bytes are 00238 // less than a record header size we must throw them away. 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 // If this is the unpacked case we need to check for bytes being thrown away 00252 // on the current page or the last page. 00253 // 00254 00255 } else { 00256 00257 // 00258 // If there is an active Lbcb, we need to add any bytes that 00259 // would be thrown away at the end. 00260 // 00261 00262 if (CurrentPageBytes != 0) { 00263 00264 // 00265 // We won't use this log page unless the new log record will fit or 00266 // unless this is the first log record in the page. 00267 // 00268 00269 if ((CurrentPageBytes != (ULONG)Lfcb->LogPageDataSize) 00270 && (CurrentLogRecordSize > CurrentPageBytes)) { 00271 00272 CurrentLogRecordSize += CurrentPageBytes; 00273 00274 // 00275 // Remember that we will start this log record at the first 00276 // byte in the data portion of a page. 00277 // 00278 00279 LogRecordStart = 0; 00280 00281 // 00282 // Otherwise this will start at the current offset into the 00283 // data portion of the log page. 00284 // 00285 00286 } else { 00287 00288 LogRecordStart = (ULONG)Lfcb->LogPageDataSize - CurrentPageBytes; 00289 } 00290 00291 // 00292 // If there was no Lbcb, then we know that we will start at the first 00293 // byte of the data portion. 00294 // 00295 00296 } else { 00297 00298 LogRecordStart = 0; 00299 } 00300 00301 // 00302 // We always assume that we will use up the rest of the bytes on the last page 00303 // in computing whether the log record will fit in the available space. We 00304 // only subtract that space from the available space if this is a force write. 00305 // 00306 00307 if (ForceToDisk) { 00308 00309 // 00310 // We take into account where we start on a log page and continue 00311 // to subtract log pages until we know the amount on the last 00312 // page. 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 // We now know the number of bytes needed for the current log page. 00330 // Next we compute the number of bytes being reserved by UndoRequirement. 00331 // If the UndoRequirement is positive, we will add to the amount reserved 00332 // in the log file. If it is negative, we will subtract from the amount 00333 // reserved in the log file. 00334 // 00335 00336 // 00337 // When we have an actual reserve amount, we convert it to positive 00338 // and then reserve twice the space required to hold the data and 00339 // its header (up to the maximum of a single page. 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 // Now compute the net log file usage. The result may be positive or 00360 // negative. 00361 // 00362 00363 LogFileUsage = ((LONG) CurrentLogRecordSize) + UndoRequirement; //**** xxFromLong( ((LONG) CurrentLogRecordSize) + UndoRequirement ); 00364 00365 // 00366 // The actual available space is the CurrentAvail minus the reserved 00367 // undo value in the Lfcb. 00368 // 00369 00370 CurrentAvailSpace = CurrentAvailSpace - Lfcb->TotalUndoCommitment; //**** xxSub( CurrentAvailSpace, Lfcb->TotalUndoCommitment ); 00371 00372 // 00373 // If this log file usage is greater than the available log file space 00374 // then we raise a status code. 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; //**** xxAdd( Lfcb->TotalUndoCommitment, xxFromLong( UndoRequirement )); 00393 00394 Lch->ClientUndoCommitment = Lch->ClientUndoCommitment + UndoRequirement; //**** xxAdd( Lch->ClientUndoCommitment, xxFromLong( UndoRequirement )); 00395 00396 DebugTrace( -1, Dbg, "LfsVerifyLogSpaceAvail: Exit\n", 0 ); 00397 00398 // 00399 // Now check if the log file is almost used up. 00400 // 00401 00402 if ((CurrentAvailSpace - LogFileUsage) < (Lfcb->TotalAvailable >> 2)) { 00403 00404 return TRUE; 00405 } 00406 00407 return FALSE; 00408 }


Generated on Sat May 15 19:46:07 2004 for test by doxygen 1.3.7