summaryrefslogtreecommitdiff
path: root/filesys/fastfat/allocsup.c
diff options
context:
space:
mode:
authorkarlf <[email protected]>2016-08-11 13:28:13 -0700
committerkarlf <[email protected]>2016-08-11 13:28:13 -0700
commit96eb96dfb613e4c745db6bd1f53a92fe7e2290fc (patch)
treead5f3ede5cbcd6b598677ce41bcf8318471bdd92 /filesys/fastfat/allocsup.c
parent687b274aa38fd05c8c26e3068932121876d7f745 (diff)
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'filesys/fastfat/allocsup.c')
-rw-r--r--filesys/fastfat/allocsup.c257
1 files changed, 151 insertions, 106 deletions
diff --git a/filesys/fastfat/allocsup.c b/filesys/fastfat/allocsup.c
index d5850827..50a470ee 100644
--- a/filesys/fastfat/allocsup.c
+++ b/filesys/fastfat/allocsup.c
@@ -681,9 +681,9 @@ Arguments:
DebugTrace(+1, Dbg, "FatLookupFileAllocation\n", 0);
DebugTrace( 0, Dbg, " FcbOrDcb = %p\n", FcbOrDcb);
DebugTrace( 0, Dbg, " Vbo = %8lx\n", Vbo);
- DebugTrace( 0, Dbg, " Lbo = %8lx\n", Lbo);
- DebugTrace( 0, Dbg, " ByteCount = %8lx\n", ByteCount);
- DebugTrace( 0, Dbg, " Allocated = %8lx\n", Allocated);
+ DebugTrace( 0, Dbg, " pLbo = %8lx\n", Lbo);
+ DebugTrace( 0, Dbg, " pByteCount = %8lx\n", ByteCount);
+ DebugTrace( 0, Dbg, " pAllocated = %8lx\n", Allocated);
Context.Bcb = NULL;
@@ -1134,7 +1134,6 @@ Arguments:
FatLookupFileAllocationSize( IrpContext, FcbOrDcb );
}
-
//
// Check for the benign case that the desired allocation is already
// within the allocation size.
@@ -1427,8 +1426,7 @@ VOID
FatTruncateFileAllocation (
IN PIRP_CONTEXT IrpContext,
IN PFCB FcbOrDcb,
- IN ULONG DesiredAllocationSize,
- IN BOOLEAN ForDeletion
+ IN ULONG DesiredAllocationSize
)
/*++
@@ -1471,11 +1469,8 @@ Return Value:
PAGED_CODE();
- UNREFERENCED_PARAMETER( ForDeletion );
-
Vcb = FcbOrDcb->Vcb;
-
DebugTrace(+1, Dbg, "FatTruncateFileAllocation\n", 0);
DebugTrace( 0, Dbg, " FcbOrDcb = %p\n", FcbOrDcb);
DebugTrace( 0, Dbg, " DesiredAllocationSize = %8lx\n", DesiredAllocationSize);
@@ -2592,6 +2587,12 @@ Arguments:
+//
+// Limit our zeroing writes to 1 MB.
+//
+
+#define MAX_ZERO_MDL_SIZE (1*1024*1024)
+
_Requires_lock_held_(_Global_critical_region_)
VOID
FatDeallocateDiskSpace (
@@ -2647,6 +2648,8 @@ Return Value:
PFAT_WINDOW Window;
+ NTSTATUS ZeroingStatus = STATUS_SUCCESS;
+
PAGED_CODE();
DebugTrace(+1, Dbg, "FatDeallocateDiskSpace\n", 0);
@@ -2669,139 +2672,175 @@ Return Value:
if (ZeroOnDeallocate) {
- NTSTATUS Status = STATUS_SUCCESS;
- PIRP IoIrp;
- KEVENT IoEvent;
- IO_STATUS_BLOCK Iosb;
- PVOID Buffer = NULL;
- PMDL Mdl;
- ULONG ByteCountToZero;
- ULONG MdlSizeMapped;
-
- //
- // Issue the writes down for each run in the Mcb
- //
-
- KeInitializeEvent( &IoEvent,
- NotificationEvent,
- FALSE );
-
- for ( McbIndex = 0; McbIndex < RunsInMcb; McbIndex++ ) {
-
- FatGetNextMcbEntry( Vcb, Mcb, McbIndex, &Vbo, &Lbo, &ByteCount );
-
- //
- // Assert that Fat files have no holes.
- //
+ try {
- NT_ASSERT( Lbo != 0 );
+ PIRP IoIrp;
+ KEVENT IoEvent;
+ IO_STATUS_BLOCK Iosb;
+ PVOID Buffer = NULL;
+ PMDL Mdl;
+ ULONG ByteCountToZero;
+ ULONG MdlSizeMapped;
//
- // Setup our MDL for the this run.
+ // Issue the writes down for each run in the Mcb
//
- Mdl = FatBuildZeroMdl( IrpContext, ByteCount);
- if (!Mdl) {
- FatNormalizeAndRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES);
- }
+ KeInitializeEvent( &IoEvent,
+ NotificationEvent,
+ FALSE );
+
+ for ( McbIndex = 0; McbIndex < RunsInMcb; McbIndex++ ) {
- try {
+ FatGetNextMcbEntry( Vcb, Mcb, McbIndex, &Vbo, &Lbo, &ByteCount );
//
- // Map the MDL.
+ // Assert that Fat files have no holes.
//
- Buffer = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority|MdlMappingNoExecute);
- if (!Buffer) {
- FatNormalizeAndRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES);
- }
+ NT_ASSERT( Lbo != 0 );
//
- // We might not have not been able to get an MDL big enough to map the whole
- // run. In this case, break up the write.
+ // Setup our MDL for the this run.
//
- MdlSizeMapped = min( ByteCount, Mdl->ByteCount );
- ByteCountToZero = ByteCount;
+ if (ByteCount > MAX_ZERO_MDL_SIZE) {
+ Mdl = FatBuildZeroMdl( IrpContext, MAX_ZERO_MDL_SIZE);
+ } else {
+ Mdl = FatBuildZeroMdl( IrpContext, ByteCount);
+ }
- //
- // Loop until there are no bytes left to write
- //
+ if (!Mdl) {
+ ZeroingStatus = STATUS_INSUFFICIENT_RESOURCES;
+ goto try_exit;
+ }
- while (ByteCountToZero != 0) {
+ try {
//
- // Write zeros to each run.
+ // Map the MDL.
//
- KeClearEvent( &IoEvent );
-
- IoIrp = IoBuildSynchronousFsdRequest( IRP_MJ_WRITE,
- Vcb->TargetDeviceObject,
- Buffer,
- MdlSizeMapped,
- (PLARGE_INTEGER)&Lbo,
- &IoEvent,
- &Iosb );
+ Buffer = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority|MdlMappingNoExecute);
+ if (!Buffer) {
+ NT_ASSERT( FALSE );
+ ZeroingStatus = STATUS_INSUFFICIENT_RESOURCES;
+ goto try_exit2;
+ }
- if (IoIrp == NULL) {
+ //
+ // We might not have not been able to get an MDL big enough to map the whole
+ // run. In this case, break up the write.
+ //
- FatRaiseStatus( IrpContext,
- STATUS_INSUFFICIENT_RESOURCES );
- }
+ MdlSizeMapped = min( ByteCount, Mdl->ByteCount );
+ ByteCountToZero = ByteCount;
//
- // Set a flag indicating that we want to write through any
- // cache on the controller. This eliminates the need for
- // an explicit flush-device after the write.
+ // Loop until there are no bytes left to write
//
- SetFlag( IoGetNextIrpStackLocation(IoIrp)->Flags, SL_WRITE_THROUGH );
+ while (ByteCountToZero != 0) {
- Status = IoCallDriver( Vcb->TargetDeviceObject, IoIrp );
+ //
+ // Write zeros to each run.
+ //
- if (Status == STATUS_PENDING) {
+ KeClearEvent( &IoEvent );
- (VOID)KeWaitForSingleObject( &IoEvent,
- Executive,
- KernelMode,
- FALSE,
- (PLARGE_INTEGER)NULL );
+ IoIrp = IoBuildSynchronousFsdRequest( IRP_MJ_WRITE,
+ Vcb->TargetDeviceObject,
+ Buffer,
+ MdlSizeMapped,
+ (PLARGE_INTEGER)&Lbo,
+ &IoEvent,
+ &Iosb );
- Status = Iosb.Status;
- }
+ if (IoIrp == NULL) {
+ NT_ASSERT( FALSE );
+ ZeroingStatus = STATUS_INSUFFICIENT_RESOURCES;
+ goto try_exit2;
+ }
+
+ //
+ // Set a flag indicating that we want to write through any
+ // cache on the controller. This eliminates the need for
+ // an explicit flush-device after the write.
+ //
- if (!NT_SUCCESS( Status )) {
+ SetFlag( IoGetNextIrpStackLocation(IoIrp)->Flags, SL_WRITE_THROUGH );
- FatNormalizeAndRaiseStatus( IrpContext,
- Status );
- }
+ ZeroingStatus = IoCallDriver( Vcb->TargetDeviceObject, IoIrp );
- //
- // Decrement ByteCount
- //
+ if (ZeroingStatus == STATUS_PENDING) {
+
+ (VOID)KeWaitForSingleObject( &IoEvent,
+ Executive,
+ KernelMode,
+ FALSE,
+ (PLARGE_INTEGER)NULL );
+
+ ZeroingStatus = Iosb.Status;
+ }
+
+ if (!NT_SUCCESS( ZeroingStatus )) {
+ NT_ASSERT( FALSE );
+ goto try_exit2;
+ }
+
+ //
+ // Increment the starting offset where we will zero.
+ //
+
+ Lbo += MdlSizeMapped;
+
+ //
+ // Decrement ByteCount
+ //
- if (MdlSizeMapped <= ByteCountToZero) {
ByteCountToZero -= MdlSizeMapped;
- } else {
- MdlSizeMapped = ByteCountToZero;
+
+ if (ByteCountToZero < MdlSizeMapped) {
+ MdlSizeMapped = ByteCountToZero;
+ }
+
}
- }
+
+ try_exit2:
- } finally {
+ NOTHING;
+
+ } finally {
- if (!FlagOn( Mdl->MdlFlags, MDL_SOURCE_IS_NONPAGED_POOL) &&
- FlagOn( Mdl->MdlFlags, MDL_MAPPED_TO_SYSTEM_VA )) {
+ if (!FlagOn( Mdl->MdlFlags, MDL_SOURCE_IS_NONPAGED_POOL) &&
+ FlagOn( Mdl->MdlFlags, MDL_MAPPED_TO_SYSTEM_VA )) {
- MmUnmapLockedPages( Mdl->MappedSystemVa, Mdl );
+ MmUnmapLockedPages( Mdl->MappedSystemVa, Mdl );
+ }
+ IoFreeMdl( Mdl );
}
- IoFreeMdl( Mdl );
- }
+
+ }
+
+ try_exit:
+
+ NOTHING;
+
+ } except(FatExceptionFilter( NULL, GetExceptionInformation() )) {
+
+ //
+ // If we failed to zero for some reason, still go ahead and deallocate
+ // the clusters. Otherwise we'll leak space from the volume.
+ //
- }
+ ZeroingStatus = GetExceptionCode();
+
+ }
}
+ NT_ASSERT( NT_SUCCESS(ZeroingStatus) );
+
try {
//
@@ -4052,10 +4091,12 @@ Arguments:
}
//
- // Unpin the Bcb. For cleaning operations, we make this write-through.
+ // Unpin the Bcb. For cleaning operations or if the corruption was detected while mounting we make this write-through.
//
- if (CleaningOperation && Bcb) {
+ if ((CleaningOperation ||
+ FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNT_IN_PROGRESS)) &&
+ Bcb) {
IO_STATUS_BLOCK IgnoreStatus;
@@ -4619,10 +4660,11 @@ Return Value:
{
UCHAR Log = 0;
- PAGED_CODE();
+#if FASTFATDBG
+ ULONG OrigValue = Value;
+#endif
- DebugTrace(+1, Dbg, "LogOf\n", 0);
- DebugTrace( 0, Dbg, " Value = %8lx\n", Value);
+ PAGED_CODE();
//
// Knock bits off until we we get a one at position 0
@@ -4641,14 +4683,17 @@ Return Value:
if (Value != 0x1) {
+ DebugTrace(+1, Dbg, "LogOf\n", 0);
+ DebugTrace( 0, Dbg, " Value = %8lx\n", OrigValue);
+
DebugTrace( 0, Dbg, "Received non power of 2.\n", 0);
-
+
+ DebugTrace(-1, Dbg, "LogOf -> %8lx\n", Log);
+
#pragma prefast( suppress: 28159, "we bugcheck here because our internal data structures are seriously corrupted if this happens" )
FatBugCheck( Value, Log, 0 );
}
- DebugTrace(-1, Dbg, "LogOf -> %8lx\n", Log);
-
return Log;
}