/* * @implemented */ ULONG NTAPI FsRtlNumberOfRunsInMcb(IN PMCB Mcb) { /* Call the newer function */ return FsRtlNumberOfRunsInLargeMcb( &Mcb->DummyFieldThatSizesThisStructureCorrectly); }
NTSTATUS Ext2Flush (IN PEXT2_IRP_CONTEXT IrpContext) { NTSTATUS Status = STATUS_SUCCESS; PIRP Irp = NULL; PIO_STACK_LOCATION IrpSp = NULL; PEXT2_VCB Vcb = NULL; PEXT2_FCB Fcb = NULL; PEXT2_FCBVCB FcbOrVcb = NULL; PEXT2_CCB Ccb = NULL; PFILE_OBJECT FileObject = NULL; PDEVICE_OBJECT DeviceObject = NULL; BOOLEAN MainResourceAcquired = FALSE; __try { ASSERT(IrpContext); ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT))); DeviceObject = IrpContext->DeviceObject; // // This request is not allowed on the main device object // if (IsExt2FsDevice(DeviceObject)) { Status = STATUS_INVALID_DEVICE_REQUEST; __leave; } Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension; ASSERT(Vcb != NULL); ASSERT((Vcb->Identifier.Type == EXT2VCB) && (Vcb->Identifier.Size == sizeof(EXT2_VCB))); ASSERT(IsMounted(Vcb)); if ( IsFlagOn(Vcb->Flags, VCB_READ_ONLY) || IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) { Status = STATUS_SUCCESS; __leave; } Irp = IrpContext->Irp; IrpSp = IoGetCurrentIrpStackLocation(Irp); FileObject = IrpContext->FileObject; FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext; ASSERT(FcbOrVcb != NULL); Ccb = (PEXT2_CCB) FileObject->FsContext2; if (Ccb == NULL) { Status = STATUS_SUCCESS; __leave; } MainResourceAcquired = ExAcquireResourceExclusiveLite(&FcbOrVcb->MainResource, IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)); ASSERT(MainResourceAcquired); DEBUG(DL_INF, ("Ext2Flush-pre: total mcb records=%u\n", FsRtlNumberOfRunsInLargeMcb(&Vcb->Extents))); if (FcbOrVcb->Identifier.Type == EXT2VCB) { Ext2VerifyVcb(IrpContext, Vcb); Status = Ext2FlushFiles(IrpContext, (PEXT2_VCB)(FcbOrVcb), FALSE); if (NT_SUCCESS(Status)) { __leave; } Status = Ext2FlushVolume(IrpContext, (PEXT2_VCB)(FcbOrVcb), FALSE); if (NT_SUCCESS(Status) && IsFlagOn(Vcb->Volume->Flags, FO_FILE_MODIFIED)) { ClearFlag(Vcb->Volume->Flags, FO_FILE_MODIFIED); } } else if (FcbOrVcb->Identifier.Type == EXT2FCB) { Fcb = (PEXT2_FCB)(FcbOrVcb); Status = Ext2FlushFile(IrpContext, Fcb, Ccb); if (NT_SUCCESS(Status)) { if (IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED)) { Fcb->Mcb->FileAttr |= FILE_ATTRIBUTE_ARCHIVE; ClearFlag(FileObject->Flags, FO_FILE_MODIFIED); } } } DEBUG(DL_INF, ("Ext2Flush-post: total mcb records=%u\n", FsRtlNumberOfRunsInLargeMcb(&Vcb->Extents))); } __finally { if (MainResourceAcquired) { ExReleaseResourceLite(&FcbOrVcb->MainResource); } if (!IrpContext->ExceptionInProgress) { if (Vcb && Irp && IrpSp && (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY))) { // Call the disk driver to flush the physial media. NTSTATUS DriverStatus; PIO_STACK_LOCATION NextIrpSp; NextIrpSp = IoGetNextIrpStackLocation(Irp); *NextIrpSp = *IrpSp; IoSetCompletionRoutine( Irp, Ext2FlushCompletionRoutine, NULL, TRUE, TRUE, TRUE ); DriverStatus = IoCallDriver(Vcb->TargetDeviceObject, Irp); Status = (DriverStatus == STATUS_INVALID_DEVICE_REQUEST) ? Status : DriverStatus; IrpContext->Irp = Irp = NULL; } Ext2CompleteIrpContext(IrpContext, Status); } } return Status; }
VOID FFSFreeVcb( IN PFFS_VCB Vcb) { ASSERT(Vcb != NULL); ASSERT((Vcb->Identifier.Type == FFSVCB) && (Vcb->Identifier.Size == sizeof(FFS_VCB))); FsRtlNotifyUninitializeSync(&Vcb->NotifySync); if (Vcb->StreamObj) { if (IsFlagOn(Vcb->StreamObj->Flags, FO_FILE_MODIFIED)) { IO_STATUS_BLOCK IoStatus; CcFlushCache(&(Vcb->SectionObject), NULL, 0, &IoStatus); ClearFlag(Vcb->StreamObj->Flags, FO_FILE_MODIFIED); } if (Vcb->StreamObj->PrivateCacheMap) FFSSyncUninitializeCacheMap(Vcb->StreamObj); ObDereferenceObject(Vcb->StreamObj); Vcb->StreamObj = NULL; } #if DBG if (FsRtlNumberOfRunsInLargeMcb(&(Vcb->DirtyMcbs)) != 0) { LONGLONG DirtyVba; LONGLONG DirtyLba; LONGLONG DirtyLength; int i; for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++) { FFSPrint((DBG_INFO, "DirtyVba = %I64xh\n", DirtyVba)); FFSPrint((DBG_INFO, "DirtyLba = %I64xh\n", DirtyLba)); FFSPrint((DBG_INFO, "DirtyLen = %I64xh\n\n", DirtyLength)); } FFSBreakPoint(); } #endif FsRtlUninitializeLargeMcb(&(Vcb->DirtyMcbs)); FFSFreeMcbTree(Vcb->McbTree); if (Vcb->ffs_super_block) { ExFreePool(Vcb->ffs_super_block); Vcb->ffs_super_block = NULL; } ExDeleteResourceLite(&Vcb->McbResource); ExDeleteResourceLite(&Vcb->PagingIoResource); ExDeleteResourceLite(&Vcb->MainResource); IoDeleteDevice(Vcb->DeviceObject); }
NTSTATUS Ext2TruncateIndirectFast( PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_MCB Mcb ) { LONGLONG Vba; LONGLONG Lba; LONGLONG Length; NTSTATUS Status = STATUS_SUCCESS; int i; /* try to load all indirect blocks if mcb zone is not initialized */ if (!IsZoneInited(Mcb)) { Status = Ext2InitializeZone(IrpContext, Vcb, Mcb); if (!NT_SUCCESS(Status)) { DbgBreak(); ClearLongFlag(Mcb->Flags, MCB_ZONE_INITED); goto errorout; } } ASSERT (IsZoneInited(Mcb)); /* delete all data blocks here */ if (FsRtlNumberOfRunsInLargeMcb(&Mcb->Extents) != 0) { for (i = 0; FsRtlGetNextLargeMcbEntry(&Mcb->Extents, i, &Vba, &Lba, &Length); i++) { /* ignore the non-existing runs */ if (-1 == Lba || Vba == 0 || Length <= 0) continue; /* now do data block free */ Ext2FreeBlock(IrpContext, Vcb, (ULONG)(Lba - 1), (ULONG)Length); } } /* delete all meta blocks here */ if (FsRtlNumberOfRunsInLargeMcb(&Mcb->MetaExts) != 0) { for (i = 0; FsRtlGetNextLargeMcbEntry(&Mcb->MetaExts, i, &Vba, &Lba, &Length); i++) { /* ignore the non-existing runs */ if (-1 == Lba || Vba == 0 || Length <= 0) continue; /* now do meta block free */ Ext2FreeBlock(IrpContext, Vcb, (ULONG)(Lba - 1), (ULONG)Length); } } /* clear data and meta extents */ Ext2ClearAllExtents(&Mcb->Extents); Ext2ClearAllExtents(&Mcb->MetaExts); ClearFlag(Mcb->Flags, MCB_ZONE_INITED); /* clear inode blocks & sizes */ Mcb->Inode.i_blocks = 0; Mcb->Inode.i_size = 0; memset(&Mcb->Inode.i_block[0], 0, sizeof(__u32) * 15); /* the caller will do inode save */ errorout: return Status; }