https://git.reactos.org/?p=reactos.git;a=commitdiff;h=98ddf610bcd804bebd056…
commit 98ddf610bcd804bebd056f1916b59e46dc5388eb
Author: Trevor Thompson <tmt256(a)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);