ReactOS 0.4.15-dev-7924-g5949c20
write.c File Reference
#include "ext2fs.h"
Include dependency graph for write.c:

Go to the source code of this file.

Classes

struct  _EXT2_FLPFLUSH_CONTEXT
 

Macros

#define DL_FLP   DL_DBG
 
#define EXT2_FLPFLUSH_MAGIC   'FF2E'
 

Typedefs

typedef struct _EXT2_FLPFLUSH_CONTEXT EXT2_FLPFLUSH_CONTEXT
 
typedef struct _EXT2_FLPFLUSH_CONTEXTPEXT2_FLPFLUSH_CONTEXT
 

Functions

VOID Ext2FloppyFlush (IN PVOID Parameter)
 
VOID Ext2FloppyFlushDpc (IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
 
NTSTATUS Ext2WriteComplete (IN PEXT2_IRP_CONTEXT IrpContext)
 
NTSTATUS Ext2WriteFile (IN PEXT2_IRP_CONTEXT IrpContext)
 
NTSTATUS Ext2WriteVolume (IN PEXT2_IRP_CONTEXT IrpContext)
 
VOID Ext2DeferWrite (IN PEXT2_IRP_CONTEXT, PIRP Irp)
 
VOID Ext2StartFloppyFlushDpc (PEXT2_VCB Vcb, PEXT2_FCB Fcb, PFILE_OBJECT FileObject)
 
BOOLEAN Ext2ZeroData (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER Start, IN PLARGE_INTEGER End)
 
NTSTATUS Ext2WriteInode (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONGLONG Offset, IN PVOID Buffer, IN ULONG Size, IN BOOLEAN bDirectIo, OUT PULONG BytesWritten)
 
NTSTATUS Ext2Write (IN PEXT2_IRP_CONTEXT IrpContext)
 

Variables

PEXT2_GLOBAL Ext2Global
 

Macro Definition Documentation

◆ DL_FLP

#define DL_FLP   DL_DBG

Definition at line 18 of file write.c.

◆ EXT2_FLPFLUSH_MAGIC

#define EXT2_FLPFLUSH_MAGIC   'FF2E'

Definition at line 22 of file write.c.

Typedef Documentation

◆ EXT2_FLPFLUSH_CONTEXT

◆ PEXT2_FLPFLUSH_CONTEXT

Function Documentation

◆ Ext2DeferWrite()

VOID Ext2DeferWrite ( IN PEXT2_IRP_CONTEXT  IrpContext,
PIRP  Irp 
)

Definition at line 227 of file write.c.

228{
229 ASSERT(IrpContext->Irp == Irp);
230
231 Ext2QueueRequest(IrpContext);
232}
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS Ext2QueueRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:158
#define ASSERT(a)
Definition: mode.c:44

Referenced by Ext2WriteFile(), and Ext2WriteVolume().

◆ Ext2FloppyFlush()

VOID Ext2FloppyFlush ( IN PVOID  Parameter)

Definition at line 75 of file write.c.

76{
81
83 FileObject = Context->FileObject;
84 Fcb = Context->Fcb;
85 Vcb = Context->Vcb;
86
87 DEBUG(DL_FLP, ("Ext2FloppyFlushing ...\n"));
88
90
91 if (FileObject) {
92 ASSERT(Fcb == (PEXT2_FCB)FileObject->FsContext);
96
97 CcFlushCache(&(Fcb->SectionObject), NULL, 0, NULL);
99
101 }
102
103 if (Vcb) {
104 ExAcquireResourceExclusiveLite(&Vcb->MainResource, TRUE);
105
106 ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
107 ExReleaseResourceLite(&Vcb->PagingIoResource);
108
110 ExReleaseResourceLite(&Vcb->MainResource);
111 }
112
115}
#define DEBUG(args)
Definition: rdesktop.h:129
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
struct _EXT2_FLPFLUSH_CONTEXT * PEXT2_FLPFLUSH_CONTEXT
#define DL_FLP
Definition: write.c:18
#define EXT2_FLPFLUSH_MAGIC
Definition: write.c:22
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
NTSTATUS Ext2FlushVcb(IN PEXT2_VCB Vcb)
Definition: generic.c:323
VOID Ext2FreePool(IN PVOID P, IN ULONG Tag)
Definition: debug.c:2697
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1068
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define Vcb
Definition: cdprocs.h:1415
ERESOURCE PagingIoResource
Definition: ntfs.h:527
ERESOURCE MainResource
Definition: ntfs.h:528
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

Referenced by Ext2StartFloppyFlushDpc().

◆ Ext2FloppyFlushDpc()

VOID Ext2FloppyFlushDpc ( IN PKDPC  Dpc,
IN PVOID  DeferredContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2 
)

Definition at line 122 of file write.c.

128{
130
132
133 DEBUG(DL_FLP, ("Ext2FloppyFlushDpc is to be started...\n"));
134
136}
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
@ CriticalWorkQueue
Definition: extypes.h:189
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:687

Referenced by Ext2StartFloppyFlushDpc().

◆ Ext2StartFloppyFlushDpc()

VOID Ext2StartFloppyFlushDpc ( PEXT2_VCB  Vcb,
PEXT2_FCB  Fcb,
PFILE_OBJECT  FileObject 
)

Definition at line 139 of file write.c.

143{
144 LARGE_INTEGER OneSecond;
146
148
151 sizeof(EXT2_FLPFLUSH_CONTEXT),
153 );
154
155 if (!Context) {
156 DEBUG(DL_ERR, ( "Ex2StartFloppy...: failed to allocate Context\n"));
157 DbgBreak();
158 return;
159 }
160
161 KeInitializeTimer(&Context->Timer);
162
165 Context );
166
169 Context );
170
171 Context->Vcb = Vcb;
172 Context->Fcb = Fcb;
173 Context->FileObject = FileObject;
174
175 if (FileObject) {
177 }
178
179 OneSecond.QuadPart = (LONGLONG)-1*1000*1000*10;
180 KeSetTimer( &Context->Timer,
181 OneSecond,
182 &Context->Dpc );
183}
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
VOID Ext2FloppyFlushDpc(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: write.c:122
VOID Ext2FloppyFlush(IN PVOID Parameter)
Definition: write.c:75
#define NonPagedPool
Definition: env_spec_w32.h:307
PVOID Ext2AllocatePool(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: debug.c:2684
#define DbgBreak()
Definition: ext2fs.h:46
#define DL_ERR
Definition: ext2fs.h:1434
#define VCB_FLOPPY_DISK
Definition: ext2fs.h:806
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
int64_t LONGLONG
Definition: typedefs.h:68
LONGLONG QuadPart
Definition: typedefs.h:114
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by Ext2SaveInode(), Ext2SaveInodeXattr(), Ext2SaveSuper(), Ext2WriteFile(), and Ext2WriteInode().

◆ Ext2Write()

NTSTATUS Ext2Write ( IN PEXT2_IRP_CONTEXT  IrpContext)

Definition at line 1355 of file write.c.

1356{
1358 PEXT2_FCBVCB FcbOrVcb;
1361 PEXT2_VCB Vcb;
1362 BOOLEAN bCompleteRequest = TRUE;
1363
1364 ASSERT(IrpContext);
1365
1366 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
1367 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
1368
1369 _SEH2_TRY {
1370
1371 if (IsFlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE)) {
1372
1373 Status = Ext2WriteComplete(IrpContext);
1374 bCompleteRequest = FALSE;
1375
1376 } else {
1377
1378 DeviceObject = IrpContext->DeviceObject;
1382 }
1383 FileObject = IrpContext->FileObject;
1384
1385 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
1386
1387 if (Vcb->Identifier.Type != EXT2VCB ||
1388 Vcb->Identifier.Size != sizeof(EXT2_VCB) ) {
1391 }
1392
1393 if (IsVcbReadOnly(Vcb)) {
1396 }
1397
1398 if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED) &&
1399 Vcb->LockFile != FileObject ) {
1402 }
1403
1404 FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;
1405
1406 if (FcbOrVcb->Identifier.Type == EXT2VCB) {
1407
1408 Status = Ext2WriteVolume(IrpContext);
1409 if (!NT_SUCCESS(Status)) {
1410 DbgBreak();
1411 }
1412 bCompleteRequest = FALSE;
1413
1414 } else if (FcbOrVcb->Identifier.Type == EXT2FCB) {
1415
1416 if (IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
1419 }
1420
1421 Status = Ext2WriteFile(IrpContext);
1422 if (!NT_SUCCESS(Status)) {
1423 DbgBreak();
1424 }
1425
1426 bCompleteRequest = FALSE;
1427 } else {
1429 }
1430 }
1431
1432 } _SEH2_FINALLY {
1433
1434 if (bCompleteRequest) {
1435 Ext2CompleteIrpContext(IrpContext, Status);
1436 }
1437 } _SEH2_END;
1438
1439 return Status;
1440}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS Ext2WriteFile(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: write.c:763
NTSTATUS Ext2WriteComplete(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: write.c:1321
NTSTATUS Ext2WriteVolume(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: write.c:236
#define VCB_VOLUME_LOCKED
Definition: ext2fs.h:789
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
@ EXT2FCB
Definition: ext2fs.h:463
@ EXT2ICX
Definition: ext2fs.h:465
@ EXT2VCB
Definition: ext2fs.h:462
#define IsVcbReadOnly(Vcb)
Definition: ext2fs.h:814
#define IsExt2FsDevice(DO)
Definition: ext2fs.h:616
#define VCB_DISMOUNT_PENDING
Definition: ext2fs.h:791
struct _EXT2_FCBVCB * PEXT2_FCBVCB
struct _EXT2_VCB * PEXT2_VCB
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define _SEH2_LEAVE
Definition: filesup.c:20
Status
Definition: gdiplustypes.h:25
if(dx< 0)
Definition: linetemp.h:194
#define STATUS_TOO_LATE
Definition: ntstatus.h:626
EXT2_IDENTIFIER Identifier
Definition: ext2fs.h:633
EXT2_IDENTIFIER_TYPE Type
Definition: ext2fs.h:477
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420

Referenced by Ext2DispatchRequest().

◆ Ext2WriteComplete()

NTSTATUS Ext2WriteComplete ( IN PEXT2_IRP_CONTEXT  IrpContext)

Definition at line 1321 of file write.c.

1322{
1325 PIRP Irp;
1327
1328 _SEH2_TRY {
1329
1330 ASSERT(IrpContext);
1331 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
1332 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
1333
1334 FileObject = IrpContext->FileObject;
1335
1336 Irp = IrpContext->Irp;
1338
1339 CcMdlWriteComplete(FileObject, &(IrpSp->Parameters.Write.ByteOffset), Irp->MdlAddress);
1340 Irp->MdlAddress = NULL;
1342
1343 } _SEH2_FINALLY {
1344
1345 if (!IrpContext->ExceptionInProgress) {
1346 Ext2CompleteIrpContext(IrpContext, Status);
1347 }
1348 } _SEH2_END;
1349
1350 return Status;
1351}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define STATUS_SUCCESS
Definition: shellext.h:65
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@3983 Write
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by Ext2Write().

◆ Ext2WriteFile()

NTSTATUS Ext2WriteFile ( IN PEXT2_IRP_CONTEXT  IrpContext)

Definition at line 763 of file write.c.

764{
769
771
772 PIRP Irp = NULL;
773 PIO_STACK_LOCATION IoStackLocation = NULL;
775
779
781
782 BOOLEAN OpPostIrp = FALSE;
783 BOOLEAN PagingIo = FALSE;
784 BOOLEAN Nocache = FALSE;
785 BOOLEAN SynchronousIo = FALSE;
786
787 BOOLEAN RecursiveWriteThrough = FALSE;
788 BOOLEAN MainResourceAcquired = FALSE;
789 BOOLEAN PagingIoResourceAcquired = FALSE;
790
791 BOOLEAN bDeferred = FALSE;
792#ifndef __REACTOS__
793 BOOLEAN UpdateFileValidSize = FALSE;
794#endif
795 BOOLEAN FileSizesChanged = FALSE;
796 BOOLEAN rc;
797
798
799 _SEH2_TRY {
800
801 ASSERT(IrpContext);
802 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
803 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
804
805 DeviceObject = IrpContext->DeviceObject;
806 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
807 ASSERT(Vcb != NULL);
808 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
809 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
810
811 FileObject = IrpContext->FileObject;
812 Fcb = (PEXT2_FCB) FileObject->FsContext;
813 Ccb = (PEXT2_CCB) FileObject->FsContext2;
814 ASSERT(Fcb);
816 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
817
818 Irp = IrpContext->Irp;
819 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
820
821 Length = IoStackLocation->Parameters.Write.Length;
822 ByteOffset = IoStackLocation->Parameters.Write.ByteOffset;
823
824 PagingIo = IsFlagOn(Irp->Flags, IRP_PAGING_IO);
825 Nocache = IsFlagOn(Irp->Flags, IRP_NOCACHE);
826 SynchronousIo = IsFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);
827
828 if (PagingIo) {
829 ASSERT(Nocache);
830 }
831
832 DEBUG(DL_INF, ("Ext2WriteFile: %wZ Offset=%I64xh Length=%xh Paging=%xh Nocache=%xh\n",
833 &Fcb->Mcb->ShortName, ByteOffset.QuadPart, Length, PagingIo, Nocache));
834
835 if (IsSpecialFile(Fcb) || IsInodeSymLink(Fcb->Inode) ) {
838 }
839
840 if (IsFileDeleted(Fcb->Mcb) ||
841 (IsSymLink(Fcb) && IsFileDeleted(Fcb->Mcb->Target)) ) {
844 }
845
846 if (Length == 0) {
847 Irp->IoStatus.Information = 0;
850 }
851
853 ByteOffset.HighPart == -1) {
854 ByteOffset = FileObject->CurrentByteOffset;
855 } else if (IsWritingToEof(ByteOffset)) {
856 ByteOffset.QuadPart = Fcb->Header.FileSize.QuadPart;
857 }
858
859 if (Nocache && !PagingIo &&
860 ( (ByteOffset.LowPart & (SECTOR_SIZE - 1)) ||
861 (Length & (SECTOR_SIZE - 1))) ) {
864 }
865
866 if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
867 ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
870 }
871
872 if (!Nocache) {
873
874 BOOLEAN bAgain = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
875 BOOLEAN bWait = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
876 BOOLEAN bQueue = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
877
878 if ( !CcCanIWrite(
880 Length,
881 (bWait && bQueue),
882 bAgain ) ) {
883
885 IrpContext->Irp,
886 Length,
888
889 if (NT_SUCCESS(Status)) {
890 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
893 IrpContext,
894 Irp,
895 Length,
896 bAgain );
897 bDeferred = TRUE;
900 }
901 }
902 }
903
904 if (IsDirectory(Fcb) && !PagingIo) {
907 }
908
909 if (IsFlagOn(Irp->Flags, IRP_SYNCHRONOUS_PAGING_IO) && !IrpContext->IsTopLevel) {
910
911 PIRP TopIrp;
912
913 TopIrp = IoGetTopLevelIrp();
914
916 NodeType(TopIrp) == IO_TYPE_IRP) {
917
918 PIO_STACK_LOCATION IrpStack;
919
920 IrpStack = IoGetCurrentIrpStackLocation(TopIrp);
921
922 if ((IrpStack->MajorFunction == IRP_MJ_WRITE) &&
923 (IrpStack->FileObject->FsContext == FileObject->FsContext) &&
924 !FlagOn(TopIrp->Flags, IRP_NOCACHE) ) {
925
926 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH);
927 RecursiveWriteThrough = TRUE;
928 }
929 }
930 }
931
932 if (PagingIo) {
933
937 }
938 PagingIoResourceAcquired = TRUE;
939
940 if ( (ByteOffset.QuadPart + Length) > Fcb->Header.FileSize.QuadPart) {
941
942 if (ByteOffset.QuadPart >= Fcb->Header.AllocationSize.QuadPart) {
943
945 Irp->IoStatus.Information = 0;
947
948 } else {
949
950 ReturnedLength = (ULONG)(Fcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
951 if (ByteOffset.QuadPart + Length > Fcb->Header.AllocationSize.QuadPart)
952 Length = (ULONG)(Fcb->Header.AllocationSize.QuadPart - ByteOffset.QuadPart);
953 }
954
955 } else {
956
958 }
959
960 } else {
961
965 }
966
967 if (IsDirectory(Fcb)) {
969 }
970
974 }
975 MainResourceAcquired = TRUE;
976
977 //
978 // Do flushing for such cases
979 //
980 if (Nocache && Ccb != NULL && Fcb->SectionObject.DataSectionObject != NULL) {
981
984
985 CcFlushCache( &(Fcb->SectionObject),
986 &ByteOffset,
988 &(Irp->IoStatus));
990
991 if (!NT_SUCCESS(Irp->IoStatus.Status)) {
992 Status = Irp->IoStatus.Status;
994 }
995
998
999 CcPurgeCacheSection( &(Fcb->SectionObject),
1000 &(ByteOffset),
1002 FALSE );
1003 }
1004
1005 if (!FsRtlCheckLockForWriteAccess(&Fcb->FileLockAnchor, Irp)) {
1008 }
1009
1010 if (Ccb != NULL) {
1011 Status = FsRtlCheckOplock( &Fcb->Oplock,
1012 Irp,
1013 IrpContext,
1015 Ext2LockIrp );
1016
1017 if (Status != STATUS_SUCCESS) {
1018 OpPostIrp = TRUE;
1020 }
1021
1022 //
1023 // Set the flag indicating if Fast I/O is possible
1024 //
1025
1026 Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
1027 }
1028
1029 //
1030 // Extend the inode size when the i/o is beyond the file end ?
1031 //
1032
1033 if ((ByteOffset.QuadPart + Length) > Fcb->Header.FileSize.QuadPart) {
1034
1036
1040 }
1041 PagingIoResourceAcquired = TRUE;
1042
1043 /* let this irp wait, since it has to be synchronous */
1044 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
1045
1046 Last.QuadPart = Fcb->Header.AllocationSize.QuadPart;
1047 AllocationSize.QuadPart = (LONGLONG)(ByteOffset.QuadPart + Length);
1049 (ULONGLONG)AllocationSize.QuadPart,
1051
1052 /* tell Ext2ExpandFile to allocate unwritten extent or NULL blocks
1053 for indirect files, otherwise we might get gabage data in holes */
1054 IrpContext->MajorFunction += IRP_MJ_MAXIMUM_FUNCTION;
1055 Status = Ext2ExpandFile(IrpContext, Vcb, Fcb->Mcb, &AllocationSize);
1056 IrpContext->MajorFunction -= IRP_MJ_MAXIMUM_FUNCTION;
1057 if (AllocationSize.QuadPart > Last.QuadPart) {
1058 Fcb->Header.AllocationSize.QuadPart = AllocationSize.QuadPart;
1060 }
1062 PagingIoResourceAcquired = FALSE;
1063
1064 if (ByteOffset.QuadPart >= Fcb->Header.AllocationSize.QuadPart) {
1065 if (NT_SUCCESS(Status)) {
1066 DbgBreak();
1068 }
1070 }
1071
1072 if (ByteOffset.QuadPart + Length > Fcb->Header.AllocationSize.QuadPart) {
1073 Length = (ULONG)(Fcb->Header.AllocationSize.QuadPart - ByteOffset.QuadPart);
1074 }
1075
1076 Fcb->Header.FileSize.QuadPart = Fcb->Inode->i_size = ByteOffset.QuadPart + Length;
1077 Ext2SaveInode(IrpContext, Vcb, Fcb->Inode);
1078
1080 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
1081 }
1082
1084 FileSizesChanged = TRUE;
1085
1086 if (Fcb->Header.FileSize.QuadPart >= 0x80000000 &&
1087 !IsFlagOn(SUPER_BLOCK->s_feature_ro_compat, EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
1089 Ext2SaveSuper(IrpContext, Vcb);
1090 }
1091
1092 DEBUG(DL_IO, ("Ext2WriteFile: expanding %wZ to FS: %I64xh FA: %I64xh\n",
1093 &Fcb->Mcb->ShortName, Fcb->Header.FileSize.QuadPart,
1094 Fcb->Header.AllocationSize.QuadPart));
1095 }
1096
1098 }
1099
1100 if (!Nocache) {
1101
1102 if (FileObject->PrivateCacheMap == NULL) {
1104 FileObject,
1105 (PCC_FILE_SIZES)(&Fcb->Header.AllocationSize),
1106 FALSE,
1108 Fcb );
1109
1111 FileObject,
1113 }
1114
1115 if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
1116
1118 FileObject,
1119 &ByteOffset,
1120 Length,
1121 &Irp->MdlAddress,
1122 &Irp->IoStatus );
1123
1124 Status = Irp->IoStatus.Status;
1125
1126 } else {
1127
1129 if (Buffer == NULL) {
1130 DbgBreak();
1133 }
1134
1135 if (ByteOffset.QuadPart > Fcb->Header.ValidDataLength.QuadPart) {
1136
1137 /* let this irp wait, since it has to be synchronous */
1138 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
1139
1140 rc = Ext2ZeroData(IrpContext, Vcb, FileObject,
1141 &Fcb->Header.ValidDataLength, &ByteOffset);
1142 if (!rc) {
1144 DbgBreak();
1146 }
1147 }
1148
1150 if (Ext2CanIWait() ||
1153 DbgBreak();
1155 }
1156 }
1157
1158 if (ByteOffset.QuadPart + Length > Fcb->Header.ValidDataLength.QuadPart ) {
1159
1160 if (Fcb->Header.FileSize.QuadPart < ByteOffset.QuadPart + Length) {
1161 Fcb->Header.ValidDataLength.QuadPart = Fcb->Header.FileSize.QuadPart;
1162 } else {
1163 if (Fcb->Header.ValidDataLength.QuadPart < ByteOffset.QuadPart + Length)
1164 Fcb->Header.ValidDataLength.QuadPart = ByteOffset.QuadPart + Length;
1165 }
1166
1167 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
1168 FileSizesChanged = TRUE;
1169 }
1170
1172 }
1173
1174 if (NT_SUCCESS(Status)) {
1175 Irp->IoStatus.Information = Length;
1176 if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
1177 DEBUG(DL_FLP, ("Ext2WriteFile is starting FlushingDpc...\n"));
1179 }
1180 }
1181
1182 } else {
1183
1184 if (!PagingIo && !RecursiveWriteThrough && !IsLazyWriter(Fcb)) {
1185 if (ByteOffset.QuadPart > Fcb->Header.ValidDataLength.QuadPart) {
1186
1187 /* let this irp wait, since it has to be synchronous */
1188 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
1189 rc = Ext2ZeroData(IrpContext, Vcb, FileObject,
1190 &Fcb->Header.ValidDataLength,
1191 &ByteOffset);
1192 if (!rc) {
1194 DbgBreak();
1196 }
1197 }
1198 }
1199
1201 IrpContext->Irp,
1202 Length,
1203 IoReadAccess );
1204
1205 if (!NT_SUCCESS(Status)) {
1207 }
1208
1209 Irp->IoStatus.Status = STATUS_SUCCESS;
1210 Irp->IoStatus.Information = ReturnedLength;
1211
1213 IrpContext,
1214 Vcb,
1215 Fcb->Mcb,
1216 (ULONGLONG)(ByteOffset.QuadPart),
1217 NULL,
1219 TRUE,
1220 &Length
1221 );
1222
1223 Irp = IrpContext->Irp;
1224
1225 if (NT_SUCCESS(Status) && !RecursiveWriteThrough && !IsLazyWriter(Fcb)) {
1226
1227 if (ByteOffset.QuadPart + Length > Fcb->Header.ValidDataLength.QuadPart ) {
1228
1229 FileSizesChanged = TRUE;
1230
1231 if (Fcb->Header.FileSize.QuadPart < ByteOffset.QuadPart + Length) {
1232 if (!PagingIo)
1233 Fcb->Header.FileSize.QuadPart = ByteOffset.QuadPart + Length;
1234 Fcb->Header.ValidDataLength.QuadPart = Fcb->Header.FileSize.QuadPart;
1235 } else {
1236 if (Fcb->Header.ValidDataLength.QuadPart < ByteOffset.QuadPart + Length)
1237 Fcb->Header.ValidDataLength.QuadPart = ByteOffset.QuadPart + Length;
1238 }
1239
1240 if (!PagingIo && CcIsFileCached(FileObject)) {
1241 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
1242 }
1243
1244 DEBUG(DL_IO, ("Ext2WriteFile: %wZ written FS: %I64xh FA: %I64xh BO: %I64xh LEN: %u\n",
1245 &Fcb->Mcb->ShortName, Fcb->Header.FileSize.QuadPart,
1246 Fcb->Header.AllocationSize.QuadPart, ByteOffset.QuadPart, Length));
1247 }
1248 }
1249 }
1250
1251 if (FileSizesChanged) {
1253 Ext2NotifyReportChange( IrpContext, Vcb, Fcb->Mcb,
1256 }
1257
1258 } _SEH2_FINALLY {
1259
1260 /*
1261 * in case we got excpetions, we need revert MajorFunction
1262 * back to IRP_MJ_WRITE. The reason we do this, is to tell
1263 * Ext2ExpandFile to allocate unwritten extent or don't add
1264 * new blocks for indirect files.
1265 */
1266 if (IrpContext->MajorFunction > IRP_MJ_MAXIMUM_FUNCTION)
1267 IrpContext->MajorFunction -= IRP_MJ_MAXIMUM_FUNCTION;
1268
1269 if (Irp) {
1270 if (PagingIoResourceAcquired) {
1272 }
1273
1274 if (MainResourceAcquired) {
1276 }
1277 }
1278
1279 if (!OpPostIrp && !IrpContext->ExceptionInProgress) {
1280
1281 if (Irp) {
1282
1283 if (Status == STATUS_PENDING ||
1285
1286 if (!bDeferred) {
1287 Status = Ext2QueueRequest(IrpContext);
1288 }
1289
1290 } else {
1291
1292 if (NT_SUCCESS(Status) && !PagingIo) {
1293
1294 if (SynchronousIo) {
1295 FileObject->CurrentByteOffset.QuadPart =
1296 ByteOffset.QuadPart + Irp->IoStatus.Information;
1297 }
1298
1301 }
1302
1303 Ext2CompleteIrpContext(IrpContext, Status);
1304 }
1305 } else {
1306 Ext2FreeIrpContext(IrpContext);
1307 }
1308 }
1309 } _SEH2_END;
1310
1311 DEBUG(DL_IO, ("Ext2WriteFile: %wZ written at Offset=%I64xh Length=%xh PagingIo=%d Nocache=%d "
1312 "RetLen=%xh VDL=%I64xh FileSize=%I64xh i_size=%I64xh Status=%xh\n",
1313 &Fcb->Mcb->ShortName, ByteOffset, Length, PagingIo, Nocache, ReturnedLength,
1314 Fcb->Header.ValidDataLength.QuadPart,Fcb->Header.FileSize.QuadPart,
1315 Fcb->Inode->i_size, Status));
1316
1317 return Status;
1318}
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:188
#define SECTOR_SIZE
Definition: fs.h:22
#define READ_AHEAD_GRANULARITY
Definition: btrfs_drv.h:114
VOID NTAPI CcPrepareMdlWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
Definition: mdlsup.c:91
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36
#define CcIsFileCached(FO)
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
Definition: bufpool.h:45
#define BLOCK_SIZE
Definition: dlist.c:220
#define NodeType(P)
Definition: nodetype.h:51
#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE
Definition: ext2_fs.h:466
BOOLEAN Ext2ZeroData(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER Start, IN PLARGE_INTEGER End)
Definition: write.c:186
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
VOID Ext2StartFloppyFlushDpc(PEXT2_VCB Vcb, PEXT2_FCB Fcb, PFILE_OBJECT FileObject)
Definition: write.c:139
VOID Ext2DeferWrite(IN PEXT2_IRP_CONTEXT, PIRP Irp)
Definition: write.c:227
NTSTATUS Ext2WriteInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONGLONG Offset, IN PVOID Buffer, IN ULONG Size, IN BOOLEAN bDirectIo, OUT PULONG BytesWritten)
Definition: write.c:668
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define IsSpecialFile(Fcb)
Definition: ext2fs.h:284
VOID Ext2OplockComplete(IN PVOID Context, IN PIRP Irp)
Definition: dispatch.c:45
#define Ext2FileCanWrite
Definition: ext2fs.h:432
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1088
#define IsDirectory(Fcb)
Definition: ext2fs.h:283
#define IsFileDeleted(Mcb)
Definition: ext2fs.h:968
BOOLEAN Ext2SaveInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN struct inode *Inode)
Definition: generic.c:552
#define FCB_ALLOC_IN_WRITE
Definition: ext2fs.h:885
#define SetLongFlag(_F, _SF)
Definition: ext2fs.h:258
#define DL_INF
Definition: ext2fs.h:1436
#define FCB_FILE_MODIFIED
Definition: ext2fs.h:882
VOID Ext2FreeIrpContext(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: memory.c:114
NTSTATUS Ext2LockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
Definition: block.c:113
#define SUPER_BLOCK
Definition: ext2fs.h:90
#define ClearLongFlag(_F, _SF)
Definition: ext2fs.h:259
#define IsSymLink(Fcb)
Definition: ext2fs.h:285
PVOID Ext2GetUserBuffer(IN PIRP Irp)
Definition: block.c:146
VOID Ext2NotifyReportChange(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONG Filter, IN ULONG Action)
Definition: dirctl.c:1209
#define IsInodeSymLink(I)
Definition: ext2fs.h:286
BOOLEAN Ext2SaveSuper(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: generic.c:67
#define Ext2CanIWait()
Definition: ext2fs.h:1100
#define IRP_CONTEXT_FLAG_DEFERRED
Definition: ext2fs.h:1091
#define IRP_CONTEXT_FLAG_REQUEUED
Definition: ext2fs.h:1094
VOID Ext2LockIrp(IN PVOID Context, IN PIRP Irp)
Definition: dispatch.c:94
#define IsLazyWriter(Fcb)
Definition: ext2fs.h:822
#define IsWritingToEof(Pos)
Definition: ext2fs.h:280
NTSTATUS Ext2ExpandFile(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_MCB Mcb, PLARGE_INTEGER Size)
Definition: fileinfo.c:1152
struct _EXT2_FCB * PEXT2_FCB
#define CEILING_ALIGNED(T, A, B)
Definition: ext2fs.h:111
#define DL_IO
Definition: ext2fs.h:1450
int Ext2CheckFileAccess(PEXT2_VCB Vcb, PEXT2_MCB Mcb, int attempt)
Definition: access.c:51
FAST_IO_POSSIBLE Ext2IsFastIoPossible(IN PEXT2_FCB Fcb)
Definition: fastio.c:38
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:322
BOOLEAN NTAPI FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:710
#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG
Definition: fsrtltypes.h:65
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
#define FILE_USE_FILE_POINTER_POSITION
Definition: nt_native.h:780
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN UCHAR Retrying)
Definition: copysup.c:214
VOID NTAPI CcDeferWrite(IN PFILE_OBJECT FileObject, IN PCC_POST_DEFERRED_WRITE PostRoutine, IN PVOID Context1, IN PVOID Context2, IN ULONG BytesToWrite, IN BOOLEAN Retrying)
Definition: copysup.c:225
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:320
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSTATUS NTAPI FsRtlCheckOplock(IN POPLOCK Oplock, IN PIRP Irp, IN PVOID Context, IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL)
Definition: oplock.c:1170
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
ULONG Type
Definition: ntfs.h:95
ULONG Size
Definition: ntfs.h:96
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: ext2fs.h:532
ULONG Flags
Definition: ntfs.h:536
CD_MCB Mcb
Definition: cdstruc.h:1016
NTFSIDENTIFIER Identifier
Definition: ntfs.h:515
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
VOID(NTAPI * PCC_POST_DEFERRED_WRITE)(_In_ PVOID Context1, _In_ PVOID Context2)
Definition: cctypes.h:66
#define FILE_NOTIFY_CHANGE_SIZE
#define IO_TYPE_IRP
#define FILE_ACTION_MODIFIED
#define IRP_PAGING_IO
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
#define IRP_MN_MDL
Definition: iotypes.h:4419
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1789
#define IRP_MN_DPC
Definition: iotypes.h:4418
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
#define IRP_SYNCHRONOUS_PAGING_IO
#define IRP_NOCACHE
#define IRP_MJ_MAXIMUM_FUNCTION
@ IoReadAccess
Definition: ketypes.h:863

Referenced by Ext2Write().

◆ Ext2WriteInode()

NTSTATUS Ext2WriteInode ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN PEXT2_MCB  Mcb,
IN ULONGLONG  Offset,
IN PVOID  Buffer,
IN ULONG  Size,
IN BOOLEAN  bDirectIo,
OUT PULONG  BytesWritten 
)

Definition at line 668 of file write.c.

678{
679 PEXT2_EXTENT Chain = NULL;
681
682 _SEH2_TRY {
683
684 if (BytesWritten) {
685 *BytesWritten = 0;
686 }
687
689 IrpContext,
690 Vcb,
691 Mcb,
692 Offset,
693 Size,
694 S_ISDIR(Mcb->Inode.i_mode) ? FALSE : TRUE,
695 &Chain
696 );
697
698 if (!NT_SUCCESS(Status)) {
700 }
701
702 if (Chain == NULL) {
705 }
706
707 if (bDirectIo) {
708
709 ASSERT(IrpContext != NULL);
710
711 //
712 // We assume the offset is aligned.
713 //
714
716 IrpContext,
717 Vcb,
718 Chain,
719 Size
720 );
721
722 } else {
723
725 for (Extent = Chain; Extent != NULL; Extent = Extent->Next) {
726
727 if ( !Ext2SaveBuffer(
728 IrpContext,
729 Vcb,
730 Extent->Lba,
731 Extent->Length,
732 (PVOID)((PUCHAR)Buffer + Extent->Offset)
733 )) {
735 }
736 }
737
738 if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
739
740 DEBUG(DL_FLP, ("Ext2WriteInode is starting FlushingDpc...\n"));
742 }
743
745 }
746
747 } _SEH2_FINALLY {
748
749 if (Chain) {
751 }
752
755 }
756 } _SEH2_END;
757
758 return Status;
759}
#define S_ISDIR(mode)
Definition: various.h:18
BOOLEAN Ext2SaveBuffer(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG Offset, IN ULONG Size, IN PVOID Buf)
Definition: generic.c:928
VOID Ext2DestroyExtentChain(IN PEXT2_EXTENT Chain)
Definition: memory.c:546
NTSTATUS Ext2BuildExtents(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONGLONG Offset, IN ULONG Size, IN BOOLEAN bAlloc, OUT PEXT2_EXTENT *Chain)
Definition: memory.c:1207
NTSTATUS Ext2ReadWriteBlocks(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_EXTENT Extent, IN ULONG Length)
Definition: block.c:260
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:348
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
uint64 Length
Definition: DriveVolume.h:48
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesWritten
Definition: wdfiotarget.h:960

Referenced by Ext2SetParentEntry(), Ext2WriteFile(), and Ext2WriteSymlink().

◆ Ext2WriteVolume()

NTSTATUS Ext2WriteVolume ( IN PEXT2_IRP_CONTEXT  IrpContext)

Definition at line 236 of file write.c.

237{
239
242 PEXT2_FCBVCB FcbOrVcb = NULL;
244
246
247 PIRP Irp = NULL;
248 PIO_STACK_LOCATION IoStackLocation = NULL;
249
252
253 BOOLEAN PagingIo = FALSE;
254 BOOLEAN Nocache = FALSE;
255 BOOLEAN SynchronousIo = FALSE;
256 BOOLEAN MainResourceAcquired = FALSE;
257
258 BOOLEAN bDeferred = FALSE;
259
261 PEXT2_EXTENT Chain = NULL;
262 EXT2_EXTENT BlockArray;
263
264 _SEH2_TRY {
265
266 ASSERT(IrpContext);
267 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
268 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
269
270 DeviceObject = IrpContext->DeviceObject;
271 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
272 ASSERT(Vcb != NULL);
273 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
274 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
275
276 FileObject = IrpContext->FileObject;
277 FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;
278 ASSERT(FcbOrVcb);
279
280 if (!(FcbOrVcb->Identifier.Type == EXT2VCB && (PVOID)FcbOrVcb == (PVOID)Vcb)) {
283 }
284
285 Ccb = (PEXT2_CCB) FileObject->FsContext2;
286 Irp = IrpContext->Irp;
287 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
288
289 Length = IoStackLocation->Parameters.Write.Length;
290 ByteOffset = IoStackLocation->Parameters.Write.ByteOffset;
291
292 PagingIo = IsFlagOn(Irp->Flags, IRP_PAGING_IO);
293 Nocache = IsFlagOn(Irp->Flags, IRP_NOCACHE) || (Ccb != NULL);
294 SynchronousIo = IsFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);
295
296 if (PagingIo) {
297 ASSERT(Nocache);
298 }
299
300 DEBUG(DL_INF, ("Ext2WriteVolume: Off=%I64xh Len=%xh Paging=%xh Nocache=%xh\n",
301 ByteOffset.QuadPart, Length, PagingIo, Nocache));
302
303 if (Length == 0) {
304 Irp->IoStatus.Information = 0;
307 }
308
309 if (Nocache &&
310 (ByteOffset.LowPart & (SECTOR_SIZE - 1) ||
311 Length & (SECTOR_SIZE - 1))) {
314 }
315
316 if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
317 ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
320 }
321
322 if (ByteOffset.QuadPart >=
323 Vcb->PartitionInformation.PartitionLength.QuadPart ) {
324 Irp->IoStatus.Information = 0;
327 }
328
329 if (!Nocache) {
330
331 BOOLEAN bAgain = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
332 BOOLEAN bWait = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
333 BOOLEAN bQueue = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
334
335 if ( !CcCanIWrite(
337 Length,
338 (bWait && bQueue),
339 bAgain ) ) {
340
342 IrpContext->Irp,
343 Length,
345 if (NT_SUCCESS(Status)) {
346 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
349 IrpContext,
350 Irp,
351 Length,
352 bAgain );
353
354 bDeferred = TRUE;
356
358 }
359 }
360 }
361
362 /*
363 * User direct volume access
364 */
365
366 if (Ccb != NULL && !PagingIo) {
367
369
370 if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
372 }
373
375 }
376
378 if (ByteOffset.QuadPart + Length > Vcb->Header.FileSize.QuadPart) {
379 Length = (ULONG)(Vcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
380 }
381 }
382
383 } else if (Nocache && !PagingIo && (Vcb->SectionObject.DataSectionObject != NULL)) {
384
385 ExAcquireResourceExclusiveLite(&Vcb->MainResource, TRUE);
386 MainResourceAcquired = TRUE;
387
388 ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
389 ExReleaseResourceLite(&Vcb->PagingIoResource);
390
391 CcFlushCache( &(Vcb->SectionObject),
392 &ByteOffset,
393 Length,
394 &(Irp->IoStatus));
395
396 if (!NT_SUCCESS(Irp->IoStatus.Status)) {
397 Status = Irp->IoStatus.Status;
399 }
400
401 ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
402 ExReleaseResourceLite(&Vcb->PagingIoResource);
403
404 CcPurgeCacheSection( &(Vcb->SectionObject),
406 Length,
407 FALSE );
408
409 ExReleaseResourceLite(&Vcb->MainResource);
410 MainResourceAcquired = FALSE;
411 }
412
413 if ( (ByteOffset.QuadPart + Length) > Vcb->Header.FileSize.QuadPart) {
414 Length = (ULONG)(Vcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
415 }
416
417 if (!Nocache) {
418
419 if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
420
422 Vcb->Volume,
423 &ByteOffset,
424 Length,
425 &Irp->MdlAddress,
426 &Irp->IoStatus );
427
428 Status = Irp->IoStatus.Status;
429
430 } else {
431
433 if (Buffer == NULL) {
434 DbgBreak();
435
438 }
439
440 if (!CcCopyWrite( Vcb->Volume,
442 Length,
443 TRUE,
444 Buffer )) {
447 }
448
449 Status = Irp->IoStatus.Status;
451 }
452
453 if (NT_SUCCESS(Status)) {
454 Irp->IoStatus.Information = Length;
455 }
456
457 } else if (PagingIo) {
458
459 LONGLONG DirtyStart;
460 LONGLONG DirtyLba;
461 LONGLONG DirtyLength;
462 LONGLONG RemainLength;
463
466
467 Length &= ~((ULONG)SECTOR_SIZE - 1);
468
469 Status = Ext2LockUserBuffer(IrpContext->Irp, Length, IoReadAccess);
470 if (!NT_SUCCESS(Status)) {
472 }
473
474 DirtyLba = ByteOffset.QuadPart;
475 RemainLength = (LONGLONG) Length;
476
478
479 while (RemainLength > 0) {
480
481 DirtyStart = DirtyLba;
482 ASSERT(DirtyStart >= ByteOffset.QuadPart);
483 ASSERT(DirtyStart <= ByteOffset.QuadPart + Length);
484
485 if (Ext2LookupVcbExtent(Vcb, DirtyStart, &DirtyLba, &DirtyLength)) {
486
487 if (DirtyLba == -1) {
488
489 DirtyLba = DirtyStart + DirtyLength;
490 if (ByteOffset.QuadPart + Length > DirtyLba) {
491 RemainLength = ByteOffset.QuadPart + Length - DirtyLba;
492 ASSERT(DirtyStart >= ByteOffset.QuadPart);
493 ASSERT(DirtyStart <= ByteOffset.QuadPart + Length);
494 } else {
495 RemainLength = 0;
496 }
497 continue;
498 }
499
500 ASSERT(DirtyLba <= DirtyStart);
502
503 if (!Extent) {
504 DEBUG(DL_ERR, ( "Ex2WriteVolume: failed to allocate Extent\n"));
507 }
508
509 Extent->Irp = NULL;
510 Extent->Lba = DirtyStart;
511 Extent->Offset = (ULONG)( DirtyStart + Length -
512 RemainLength - DirtyLba );
513 ASSERT(Extent->Offset <= Length);
514
515 if (DirtyLba + DirtyLength >= DirtyStart + RemainLength) {
516 Extent->Length = (ULONG)( DirtyLba +
517 RemainLength -
518 DirtyStart );
520 RemainLength = 0;
521 } else {
522 Extent->Length = (ULONG)(DirtyLength + DirtyLba - DirtyStart);
523 RemainLength = RemainLength - Extent->Length;
524/*
525 RemainLength = (DirtyStart + RemainLength) -
526 (DirtyLba + DirtyLength);
527*/
528 ASSERT(RemainLength <= (LONGLONG)Length);
530 }
531
533 DirtyLba = DirtyStart + Extent->Length;
534
535 if (List) {
536 List->Next = Extent;
537 List = Extent;
538 } else {
539 Chain = List = Extent;
540 }
541
542 } else {
543
544 if (RemainLength > SECTOR_SIZE) {
545 DirtyLba = DirtyStart + SECTOR_SIZE;
546 RemainLength -= SECTOR_SIZE;
547 } else {
548 RemainLength = 0;
549 }
550 }
551 }
552
553 if (Chain) {
554 Status = Ext2ReadWriteBlocks(IrpContext,
555 Vcb,
556 Chain,
557 Length );
558 Irp = IrpContext->Irp;
559
560 if (NT_SUCCESS(Status)) {
561 for (Extent = Chain; Extent != NULL; Extent = Extent->Next) {
563 }
564 }
565
566 if (!Irp) {
568 }
569
570 } else {
571
572 Irp->IoStatus.Information = Length;
575 }
576
577 } else {
578
579 Length &= ~((ULONG)SECTOR_SIZE - 1);
580
582 IrpContext->Irp,
583 Length,
585
586 if (!NT_SUCCESS(Status)) {
588 }
589
590 BlockArray.Irp = NULL;
591 BlockArray.Lba = ByteOffset.QuadPart;
592 BlockArray.Offset = 0;
593 BlockArray.Length = Length;
594 BlockArray.Next = NULL;
595
596 Status = Ext2ReadWriteBlocks(IrpContext,
597 Vcb,
598 &BlockArray,
599 Length );
600
601 if (NT_SUCCESS(Status)) {
602 Irp->IoStatus.Information = Length;
603 }
604
605 Irp = IrpContext->Irp;
606 if (!Irp) {
608 }
609 }
610
611 } _SEH2_FINALLY {
612
613 if (MainResourceAcquired) {
614 ExReleaseResourceLite(&Vcb->MainResource);
615 }
616
617 if (!IrpContext->ExceptionInProgress) {
618
619 if (Irp) {
620
621 if (Status == STATUS_PENDING) {
622
623 if (!bDeferred) {
625 IrpContext->Irp,
626 Length,
627 IoReadAccess );
628
629 if (NT_SUCCESS(Status)) {
630 Status = Ext2QueueRequest(IrpContext);
631 } else {
632 Ext2CompleteIrpContext(IrpContext, Status);
633 }
634 }
635
636 } else {
637
638 if (NT_SUCCESS(Status)) {
639
640 if (SynchronousIo && !PagingIo) {
641 FileObject->CurrentByteOffset.QuadPart =
642 ByteOffset.QuadPart + Irp->IoStatus.Information;
643 }
644
645 if (!PagingIo) {
647 }
648 }
649
650 Ext2CompleteIrpContext(IrpContext, Status);
651 }
652
653 } else {
654
655 Ext2FreeIrpContext(IrpContext);
656 }
657 }
658
659 if (Chain) {
661 }
662 } _SEH2_END;
663
664 return Status;
665}
#define CCB_VOLUME_DASD_PURGE
Definition: ext2fs.h:1032
NTSTATUS Ext2PurgeVolume(IN PEXT2_VCB Vcb, IN BOOLEAN FlushBeforePurge)
Definition: fsctl.c:2704
PEXT2_EXTENT Ext2AllocateExtent()
Definition: memory.c:488
BOOLEAN Ext2LookupVcbExtent(IN PEXT2_VCB Vcb, IN LONGLONG Vbn, OUT PLONGLONG Lbn, OUT PLONGLONG Length)
Definition: memory.c:747
BOOLEAN Ext2RemoveVcbExtent(IN PEXT2_VCB Vcb, IN LONGLONG Vbn, IN LONGLONG Length)
Definition: memory.c:700
struct _EXT2_CCB * PEXT2_CCB
#define CCB_ALLOW_EXTENDED_DASD_IO
Definition: ext2fs.h:1037
BOOLEAN Ext2AddVcbExtent(IN PEXT2_VCB Vcb, IN LONGLONG Vbn, IN LONGLONG Length)
Definition: memory.c:648
#define STATUS_END_OF_FILE
Definition: shellext.h:67
ULONG Length
Definition: ext2fs.h:1122
LONGLONG Lba
Definition: ext2fs.h:1120
struct _EXT2_EXTENT * Next
Definition: ext2fs.h:1124
PIRP Irp
Definition: ext2fs.h:1123
ULONG Offset
Definition: ext2fs.h:1121
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
@ IoWriteAccess
Definition: ketypes.h:864

Referenced by Ext2Write().

◆ Ext2ZeroData()

BOOLEAN Ext2ZeroData ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  Start,
IN PLARGE_INTEGER  End 
)

Definition at line 186 of file write.c.

193{
195 PBCB Bcb;
196 PVOID Ptr;
197 ULONG Size;
198 BOOLEAN rc = TRUE;
199
200 ASSERT (End && Start && End->QuadPart > Start->QuadPart);
201 Fcb = (PEXT2_FCB) FileObject->FsContext;
202
203 /* skip data zero if we've already tracked unwritten part */
204 if (0 == ( End->LowPart & (BLOCK_SIZE -1)) &&
205 0 == (Start->LowPart & (BLOCK_SIZE -1))) {
206
207 if (INODE_HAS_EXTENT(Fcb->Inode)) {
208 return TRUE;
209 } else {
210#if !EXT2_PRE_ALLOCATION_SUPPORT
211 return TRUE;
212#endif
213 }
214 }
215
216 /* clear data in range [Start, End) */
217 _SEH2_TRY {
220 DbgBreak();
221 } _SEH2_END;
222
223 return rc;
224}
#define INODE_HAS_EXTENT(i)
Definition: ext4_ext.h:228
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:414
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
Definition: fssup.c:414
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
@ Start
Definition: partlist.h:33

Referenced by Ext2WriteFile().

Variable Documentation

◆ Ext2Global

PEXT2_GLOBAL Ext2Global
extern