https://git.reactos.org/?p=reactos.git;a=commitdiff;h=98ddf610bcd804bebd056f...
commit 98ddf610bcd804bebd056f1916b59e46dc5388eb Author: Trevor Thompson tmt256@email.vccs.edu AuthorDate: Fri Jun 23 17:30:13 2017 +0000
[NTFS] - Fix IncreaseMftSize(); check IrpContext to see if waiting for exclusive access to the MFT is allowed. As pointed out by Pierre.
svn path=/branches/GSoC_2016/NTFS/; revision=75170 --- drivers/filesystems/ntfs/create.c | 24 ++++++++++++++++-------- drivers/filesystems/ntfs/mft.c | 27 +++++++++++++++++++-------- drivers/filesystems/ntfs/ntfs.h | 6 ++++-- 3 files changed, 39 insertions(+), 18 deletions(-)
diff --git a/drivers/filesystems/ntfs/create.c b/drivers/filesystems/ntfs/create.c index 07a9f5ac3e..96f563e75d 100644 --- a/drivers/filesystems/ntfs/create.c +++ b/drivers/filesystems/ntfs/create.c @@ -323,7 +323,7 @@ NtfsOpenFile(PDEVICE_EXTENSION DeviceExt, static NTSTATUS NtfsCreateFile(PDEVICE_OBJECT DeviceObject, - PIRP Irp) + PNTFS_IRP_CONTEXT IrpContext) { PDEVICE_EXTENSION DeviceExt; PIO_STACK_LOCATION Stack; @@ -334,8 +334,9 @@ NtfsCreateFile(PDEVICE_OBJECT DeviceObject, // PWSTR FileName; NTSTATUS Status; UNICODE_STRING FullPath; + PIRP Irp = IrpContext->Irp;
- DPRINT1("NtfsCreateFile(%p, %p) called\n", DeviceObject, Irp); + DPRINT1("NtfsCreateFile(%p, %p) called\n", DeviceObject, IrpContext);
DeviceExt = DeviceObject->DeviceExtension; ASSERT(DeviceExt); @@ -561,7 +562,7 @@ NtfsCreateFile(PDEVICE_OBJECT DeviceObject, }
// Create the file record on disk - Status = NtfsCreateFileRecord(DeviceExt, FileObject); + Status = NtfsCreateFileRecord(DeviceExt, FileObject, BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)); if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: Couldn't create file record!\n"); @@ -569,7 +570,7 @@ NtfsCreateFile(PDEVICE_OBJECT DeviceObject, }
// Now we should be able to open the file - return NtfsCreateFile(DeviceObject, Irp); + return NtfsCreateFile(DeviceObject, IrpContext); } }
@@ -615,7 +616,7 @@ NtfsCreate(PNTFS_IRP_CONTEXT IrpContext) ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE); Status = NtfsCreateFile(DeviceObject, - IrpContext->Irp); + IrpContext); ExReleaseResourceLite(&DeviceExt->DirResource);
return Status; @@ -634,13 +635,20 @@ NtfsCreate(PNTFS_IRP_CONTEXT IrpContext) * @param FileObject * Pointer to a FILE_OBJECT describing the file to be created * +* @param CanWait +* Boolean indicating if the function is allowed to wait for exclusive access to the master file table. +* This will only be relevant if the MFT doesn't have any free file records and needs to be enlarged. +* * @return * STATUS_SUCCESS on success. * STATUS_INSUFFICIENT_RESOURCES if unable to allocate memory for the file record. +* STATUS_CANT_WAIT if CanWait was FALSE and the function needed to resize the MFT but +* couldn't get immediate, exclusive access to it. */ NTSTATUS NtfsCreateFileRecord(PDEVICE_EXTENSION DeviceExt, - PFILE_OBJECT FileObject) + PFILE_OBJECT FileObject, + BOOLEAN CanWait) { NTSTATUS Status = STATUS_SUCCESS; PFILE_RECORD_HEADER FileRecord; @@ -649,7 +657,7 @@ NtfsCreateFileRecord(PDEVICE_EXTENSION DeviceExt, ULONGLONG ParentMftIndex; ULONGLONG FileMftIndex;
- DPRINT1("NtfsCreateFileRecord(%p, %p)\n", DeviceExt, FileObject); + DPRINT1("NtfsCreateFileRecord(%p, %p, %s)\n", DeviceExt, FileObject, CanWait ? "TRUE" : "FALSE");
// allocate memory for file record FileRecord = ExAllocatePoolWithTag(NonPagedPool, @@ -708,7 +716,7 @@ NtfsCreateFileRecord(PDEVICE_EXTENSION DeviceExt, NtfsDumpFileRecord(DeviceExt, FileRecord);
// Now that we've built the file record in memory, we need to store it in the MFT. - Status = AddNewMftEntry(FileRecord, DeviceExt, &FileMftIndex); + Status = AddNewMftEntry(FileRecord, DeviceExt, &FileMftIndex, CanWait); if (NT_SUCCESS(Status)) { // The highest 2 bytes should be the sequence number, unless the parent happens to be root diff --git a/drivers/filesystems/ntfs/mft.c b/drivers/filesystems/ntfs/mft.c index 62b2979031..8df62ed542 100644 --- a/drivers/filesystems/ntfs/mft.c +++ b/drivers/filesystems/ntfs/mft.c @@ -195,10 +195,16 @@ AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord) * @param Vcb * Pointer to the VCB (DEVICE_EXTENSION) of the target volume. * +* +* @param CanWait +* Boolean indicating if the function is allowed to wait for exclusive access to the master file table. +* This will only be relevant if the MFT doesn't have any free file records and needs to be enlarged. +* * @return * STATUS_SUCCESS on success. * STATUS_INSUFFICIENT_RESOURCES if an allocation fails. * STATUS_INVALID_PARAMETER if there was an error reading the Mft's bitmap. +* STATUS_CANT_WAIT if CanWait was FALSE and the function could not get immediate, exclusive access to the MFT. * * @remarks * Increases the size of the Master File Table by 8 records. Bitmap entries for the new records are cleared, @@ -206,7 +212,7 @@ AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord) * This function will wait for exlusive access to the volume fcb. */ NTSTATUS -IncreaseMftSize(PDEVICE_EXTENSION Vcb) +IncreaseMftSize(PDEVICE_EXTENSION Vcb, BOOLEAN CanWait) { PNTFS_ATTR_CONTEXT BitmapContext; LARGE_INTEGER BitmapSize; @@ -221,10 +227,10 @@ IncreaseMftSize(PDEVICE_EXTENSION Vcb) ULONG LengthWritten; NTSTATUS Status;
- DPRINT1("IncreaseMftSize(%p)\n", Vcb); + DPRINT1("IncreaseMftSize(%p, %s)\n", Vcb, CanWait ? "TRUE" : "FALSE");
// We need exclusive access to the mft while we change its size - if (!ExAcquireResourceExclusiveLite(&(Vcb->DirResource), TRUE)) + if (!ExAcquireResourceExclusiveLite(&(Vcb->DirResource), CanWait)) { return STATUS_CANT_WAIT; } @@ -1638,17 +1644,22 @@ FixupUpdateSequenceArray(PDEVICE_EXTENSION Vcb, * @param DestinationIndex * Pointer to a ULONGLONG which will receive the MFT index where the file record was stored. * +* @param CanWait +* Boolean indicating if the function is allowed to wait for exclusive access to the master file table. +* This will only be relevant if the MFT doesn't have any free file records and needs to be enlarged. +* * @return * STATUS_SUCCESS on success. * STATUS_OBJECT_NAME_NOT_FOUND if we can't find the MFT's $Bitmap or if we weren't able * to read the attribute. * STATUS_INSUFFICIENT_RESOURCES if we can't allocate enough memory for a copy of $Bitmap. -* +* STATUS_CANT_WAIT if CanWait was FALSE and the function could not get immediate, exclusive access to the MFT. */ NTSTATUS AddNewMftEntry(PFILE_RECORD_HEADER FileRecord, PDEVICE_EXTENSION DeviceExt, - PULONGLONG DestinationIndex) + PULONGLONG DestinationIndex, + BOOLEAN CanWait) { NTSTATUS Status = STATUS_SUCCESS; ULONGLONG MftIndex; @@ -1661,7 +1672,7 @@ AddNewMftEntry(PFILE_RECORD_HEADER FileRecord, LARGE_INTEGER BitmapBits; UCHAR SystemReservedBits;
- DPRINT1("AddNewMftEntry(%p, %p, %p)\n", FileRecord, DeviceExt, DestinationIndex); + DPRINT1("AddNewMftEntry(%p, %p, %p, %s)\n", FileRecord, DeviceExt, DestinationIndex, CanWait ? "TRUE" : "FALSE");
// First, we have to read the mft's $Bitmap attribute Status = FindAttribute(DeviceExt, DeviceExt->MasterFileTable, AttributeBitmap, L"", 0, &BitmapContext, NULL); @@ -1717,14 +1728,14 @@ AddNewMftEntry(PFILE_RECORD_HEADER FileRecord, ReleaseAttributeContext(BitmapContext);
// Couldn't find a free record in the MFT, add some blank records and try again - Status = IncreaseMftSize(DeviceExt); + Status = IncreaseMftSize(DeviceExt, CanWait); if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: Couldn't find space in MFT for file or increase MFT size!\n"); return Status; }
- return AddNewMftEntry(FileRecord, DeviceExt, DestinationIndex); + return AddNewMftEntry(FileRecord, DeviceExt, DestinationIndex, CanWait); }
DPRINT1("Creating file record at MFT index: %I64u\n", MftIndex); diff --git a/drivers/filesystems/ntfs/ntfs.h b/drivers/filesystems/ntfs/ntfs.h index b9336758ef..799f8e2a4f 100644 --- a/drivers/filesystems/ntfs/ntfs.h +++ b/drivers/filesystems/ntfs/ntfs.h @@ -667,7 +667,8 @@ NtfsCreate(PNTFS_IRP_CONTEXT IrpContext);
NTSTATUS NtfsCreateFileRecord(PDEVICE_EXTENSION DeviceExt, - PFILE_OBJECT FileObject); + PFILE_OBJECT FileObject, + BOOLEAN CanWait);
/* devctl.c */
@@ -825,7 +826,8 @@ NtfsFileSystemControl(PNTFS_IRP_CONTEXT IrpContext); NTSTATUS AddNewMftEntry(PFILE_RECORD_HEADER FileRecord, PDEVICE_EXTENSION DeviceExt, - PULONGLONG DestinationIndex); + PULONGLONG DestinationIndex, + BOOLEAN CanWait);
PNTFS_ATTR_CONTEXT PrepareAttributeContext(PNTFS_ATTR_RECORD AttrRecord);