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

write.c File Reference

#include "lfsprocs.h"

Go to the source code of this file.

Defines

#define Dbg   (DEBUG_TRACE_WRITE)

Functions

BOOLEAN LfsWrite (IN LFS_LOG_HANDLE LogHandle, IN ULONG NumberOfWriteEntries, IN PLFS_WRITE_ENTRY WriteEntries, IN LFS_RECORD_TYPE RecordType, IN TRANSACTION_ID *TransactionId OPTIONAL, IN LSN UndoNextLsn, IN LSN PreviousLsn, IN LONG UndoRequirement, OUT PLSN Lsn)
BOOLEAN LfsForceWrite (IN LFS_LOG_HANDLE LogHandle, IN ULONG NumberOfWriteEntries, IN PLFS_WRITE_ENTRY WriteEntries, IN LFS_RECORD_TYPE RecordType, IN TRANSACTION_ID *TransactionId, IN LSN UndoNextLsn, IN LSN PreviousLsn, IN LONG UndoRequirement, OUT PLSN Lsn)
VOID LfsFlushToLsn (IN LFS_LOG_HANDLE LogHandle, IN LSN Lsn)
VOID LfsCheckWriteRange (IN PLFS_WRITE_DATA WriteData, IN OUT PLONGLONG FlushOffset, IN OUT PULONG FlushLength)


Define Documentation

#define Dbg   (DEBUG_TRACE_WRITE)
 

Definition at line 28 of file lfs/write.c.


Function Documentation

VOID LfsCheckWriteRange IN PLFS_WRITE_DATA  WriteData,
IN OUT PLONGLONG  FlushOffset,
IN OUT PULONG  FlushLength
 

Definition at line 477 of file lfs/write.c.

References _LBCB::FileOffset, LFS_SIGNATURE_RECORD_PAGE_ULONG, NULL, PAGE_SIZE, PAGED_CODE, _LBCB::PageHeader, _LFCB::PageToDirty, and _LFCB::SystemPageSize.

00485 : 00486 00487 This routine is called Ntfs to Lfs when a flush occurs. This will give Lfs a chance 00488 to trim the amount of the flush. Lfs can then use a 4K log record page size 00489 for all systems (Intel and Alpha). 00490 00491 This routine will trim the size of the IO request to the value stored in the 00492 Lfcb for this volume. We will also redirty the second half of the page if 00493 we have begun writing log records into it. 00494 00495 Arguments: 00496 00497 WriteData - This is the data in the user's data structure which is maintained 00498 by Lfs to describe the current writes. 00499 00500 FlushOffset - On input this is the start of the flush passed to Ntfs from MM. 00501 On output this is the start of the actual range to flush. 00502 00503 FlushLength - On input this is the length of the flush from the given FlushOffset. 00504 On output this is the length of the flush from the possibly modified FlushOffset. 00505 00506 Return Value: 00507 00508 None 00509 00510 --*/ 00511 00512 { 00513 PLIST_ENTRY Links; 00514 PLFCB Lfcb; 00515 PLFCB NextLfcb; 00516 PAGED_CODE(); 00517 00518 // 00519 // Find the correct Lfcb for this request. 00520 // 00521 00522 Lfcb = WriteData->Lfcb; 00523 00524 // 00525 // Trim the write if not a system page size. 00526 // 00527 00528 if (PAGE_SIZE != Lfcb->SystemPageSize) { 00529 00530 // 00531 // Check if we are trimming before the write. 00532 // 00533 00534 if (*FlushOffset < WriteData->FileOffset) { 00535 00536 *FlushLength -= (ULONG) (WriteData->FileOffset - *FlushOffset); 00537 *FlushOffset = WriteData->FileOffset; 00538 } 00539 00540 // 00541 // Check that we aren't flushing too much. 00542 // 00543 00544 if (*FlushOffset + *FlushLength > WriteData->FileOffset + WriteData->Length) { 00545 00546 *FlushLength = (ULONG) (WriteData->FileOffset + WriteData->Length - *FlushOffset); 00547 } 00548 00549 // 00550 // Finally check if we have to redirty a page. 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 }

VOID LfsFlushToLsn IN LFS_LOG_HANDLE  LogHandle,
IN LSN  Lsn
 

Definition at line 360 of file lfs/write.c.

References Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), _LCH::Lfcb, LfsAcquireLch, LfsExceptionFilter(), LfsFlushToLsn(), LfsFlushToLsnPriv(), LfsReleaseLch, LfsValidateClientId, LfsValidateLch, NTSTATUS(), NULL, PAGED_CODE, and Status.

Referenced by LfsFlushToLsn().

00367 : 00368 00369 This routine is called by a client to insure that all log records 00370 to a certain point have been flushed to the file. This is done by 00371 checking if the desired Lsn has even been written at all. If so we 00372 check if it has been flushed to the file. If not, we simply write 00373 the current restart area to the disk. 00374 00375 Arguments: 00376 00377 LogHandle - Pointer to private Lfs structure used to identify this 00378 client. 00379 00380 Lsn - This is the Lsn that must be on the disk on return from this 00381 routine. 00382 00383 Return Value: 00384 00385 None 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 // Check that the structure is a valid log handle structure. 00407 // 00408 00409 LfsValidateLch( Lch ); 00410 00411 // 00412 // Use a try-except to catch errors. 00413 // 00414 00415 try { 00416 00417 // 00418 // Use a try-finally to facilitate cleanup. 00419 // 00420 00421 try { 00422 00423 // 00424 // Acquire the log file control block for this log file. 00425 // 00426 00427 LfsAcquireLch( Lch ); 00428 Lfcb = Lch->Lfcb; 00429 00430 // 00431 // If the log file has been closed we will assume the Lsn has been flushed. 00432 // 00433 00434 if (Lfcb != NULL) { 00435 00436 // 00437 // Check that the client Id is valid. 00438 // 00439 00440 LfsValidateClientId( Lfcb, Lch ); 00441 00442 // 00443 // Call our common routine to perform the work. 00444 // 00445 00446 LfsFlushToLsnPriv( Lfcb, Lsn ); 00447 } 00448 00449 } finally { 00450 00451 DebugUnwind( LfsFlushToLsn ); 00452 00453 // 00454 // Release the log file control block if held. 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 }

BOOLEAN LfsForceWrite IN LFS_LOG_HANDLE  LogHandle,
IN ULONG  NumberOfWriteEntries,
IN PLFS_WRITE_ENTRY  WriteEntries,
IN LFS_RECORD_TYPE  RecordType,
IN TRANSACTION_ID TransactionId,
IN LSN  UndoNextLsn,
IN LSN  PreviousLsn,
IN LONG  UndoRequirement,
OUT PLSN  Lsn
 

Definition at line 197 of file lfs/write.c.

References Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), FALSE, _LCH::Lfcb, LfsAcquireLch, LfsExceptionFilter(), LfsFlushToLsnPriv(), LfsForceWrite(), LfsReleaseLch, LfsValidateClientId, LfsValidateLch, LfsWriteLogRecordIntoLogPage(), NTSTATUS(), NULL, PAGED_CODE, Status, and TRUE.

00211 : 00212 00213 This routine is called by a client to write a log record to the log file. 00214 This is idendical to LfsWrite except that on return the log record is 00215 guaranteed to be on disk. 00216 00217 Arguments: 00218 00219 LogHandle - Pointer to private Lfs structure used to identify this 00220 client. 00221 00222 NumberOfWriteEntries - Number of components of the log record. 00223 00224 WriteEntries - Pointer to an array of write entries. 00225 00226 RecordType - Lfs defined type for this log record. 00227 00228 TransactionId - Id value used to group log records by complete transaction. 00229 00230 UndoNextLsn - Lsn of a previous log record which needs to be undone in 00231 the event of a client restart. 00232 00233 PreviousLsn - Lsn of the immediately previous log record for this client. 00234 00235 Lsn - Lsn to be associated with this log record. 00236 00237 Return Value: 00238 00239 BOOLEAN - Advisory, TRUE indicates that less than 1/4 of the log file is 00240 available. 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 // Check that the structure is a valid log handle structure. 00269 // 00270 00271 LfsValidateLch( Lch ); 00272 00273 // 00274 // Use a try-except to catch errors. 00275 // 00276 00277 try { 00278 00279 // 00280 // Use a try-finally to facilitate cleanup. 00281 // 00282 00283 try { 00284 00285 // 00286 // Acquire the log file control block for this log file. 00287 // 00288 00289 LfsAcquireLch( Lch ); 00290 Lfcb = Lch->Lfcb; 00291 00292 // 00293 // If the Log file has been closed then refuse access. 00294 // 00295 00296 if (Lfcb == NULL) { 00297 00298 ExRaiseStatus( STATUS_ACCESS_DENIED ); 00299 } 00300 00301 // 00302 // Check that the client Id is valid. 00303 // 00304 00305 LfsValidateClientId( Lfcb, Lch ); 00306 00307 // 00308 // Write the log record. 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 // The call to add this lbcb to the workque is guaranteed to release 00325 // the Lfcb if this thread may do the Io. 00326 // 00327 00328 LfsFlushToLsnPriv( Lfcb, *Lsn ); 00329 00330 } finally { 00331 00332 DebugUnwind( LfsForceWrite ); 00333 00334 // 00335 // Release the log file control block if held. 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 }

BOOLEAN LfsWrite IN LFS_LOG_HANDLE  LogHandle,
IN ULONG  NumberOfWriteEntries,
IN PLFS_WRITE_ENTRY  WriteEntries,
IN LFS_RECORD_TYPE  RecordType,
IN TRANSACTION_ID *TransactionId  OPTIONAL,
IN LSN  UndoNextLsn,
IN LSN  PreviousLsn,
IN LONG  UndoRequirement,
OUT PLSN  Lsn
 

Definition at line 39 of file lfs/write.c.

References Dbg, DebugTrace, DebugUnwind, ExRaiseStatus(), FALSE, _LCH::Lfcb, LfsAcquireLch, LfsExceptionFilter(), LfsReleaseLch, LfsValidateClientId, LfsValidateLch, LfsWrite(), LfsWriteLogRecordIntoLogPage(), NTSTATUS(), NULL, PAGED_CODE, PLFS_WRITE_ENTRY, and Status.

Referenced by LfsWrite().

00053 : 00054 00055 This routine is called by a client to write a log record to the log file. 00056 The log record is lazy written and is not guaranteed to be on the disk 00057 until a subsequent LfsForceWrie or LfsWriteRestartArea or until 00058 an LfsFlushtoLsn is issued withan Lsn greater-than or equal to the Lsn 00059 returned from this service. 00060 00061 Arguments: 00062 00063 LogHandle - Pointer to private Lfs structure used to identify this 00064 client. 00065 00066 NumberOfWriteEntries - Number of components of the log record. 00067 00068 WriteEntries - Pointer to an array of write entries. 00069 00070 RecordType - Lfs defined type for this log record. 00071 00072 TransactionId - Id value used to group log records by complete transaction. 00073 00074 UndoNextLsn - Lsn of a previous log record which needs to be undone in 00075 the event of a client restart. 00076 00077 PreviousLsn - Lsn of the immediately previous log record for this client. 00078 00079 Lsn - Lsn to be associated with this log record. 00080 00081 Return Value: 00082 00083 BOOLEAN - Advisory, TRUE indicates that less than 1/4 of the log file is 00084 available. 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 // Check that the structure is a valid log handle structure. 00113 // 00114 00115 LfsValidateLch( Lch ); 00116 00117 // 00118 // Use a try-except to catch errors. 00119 // 00120 00121 try { 00122 00123 // 00124 // Use a try-finally to facilitate cleanup. 00125 // 00126 00127 try { 00128 00129 // 00130 // Acquire the log file control block for this log file. 00131 // 00132 00133 LfsAcquireLch( Lch ); 00134 Lfcb = Lch->Lfcb; 00135 00136 // 00137 // If the Log file has been closed then refuse access. 00138 // 00139 00140 if (Lfcb == NULL) { 00141 00142 ExRaiseStatus( STATUS_ACCESS_DENIED ); 00143 } 00144 00145 // 00146 // Check that the client Id is valid. 00147 // 00148 00149 LfsValidateClientId( Lfcb, Lch ); 00150 00151 // 00152 // Write the log record. 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 // Release the log file control block if held. 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 }


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