From 4b68ac00e463880ba6c8cc44d20b915edb12c96c Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Sat, 25 Jan 2003 15:55:08 +0000 Subject: [PATCH] =?UTF-8?q?-Implemented=20vfat=20file=20locking.=20(Thanks?= =?UTF-8?q?=20to=20Gunnar=20Andr=EF=BF=BD=20Dalsnes)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/trunk/; revision=4065 --- reactos/drivers/fs/vfat/cleanup.c | 20 +++++++++++--- reactos/drivers/fs/vfat/fcb.c | 4 ++- reactos/drivers/fs/vfat/iface.c | 3 ++- reactos/drivers/fs/vfat/misc.c | 45 ++++++++++++++++++++++++++++++- reactos/drivers/fs/vfat/rw.c | 23 +++++++++++++++- reactos/drivers/fs/vfat/vfat.h | 3 ++- 6 files changed, 89 insertions(+), 9 deletions(-) diff --git a/reactos/drivers/fs/vfat/cleanup.c b/reactos/drivers/fs/vfat/cleanup.c index 17665266a21..c4574593a20 100644 --- a/reactos/drivers/fs/vfat/cleanup.c +++ b/reactos/drivers/fs/vfat/cleanup.c @@ -1,4 +1,4 @@ -/* $Id: cleanup.c,v 1.9 2003/01/11 15:52:54 hbirr Exp $ +/* $Id: cleanup.c,v 1.10 2003/01/25 15:55:07 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -19,14 +19,15 @@ /* FUNCTIONS ****************************************************************/ static NTSTATUS -VfatCleanupFile(PDEVICE_EXTENSION DeviceExt, - PFILE_OBJECT FileObject) +VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: Cleans up after a file has been closed. */ { PVFATCCB pCcb; PVFATFCB pFcb; + PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt; + PFILE_OBJECT FileObject = IrpContext->FileObject; DPRINT("VfatCleanupFile(DeviceExt %x, FileObject %x)\n", DeviceExt, FileObject); @@ -39,6 +40,17 @@ VfatCleanupFile(PDEVICE_EXTENSION DeviceExt, } pFcb = pCcb->pFcb; + if (!(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) && + FsRtlAreThereCurrentFileLocks(&pFcb->FileLock)) + { + /* remove all locks this process have on this file */ + FsRtlFastUnlockAll(&pFcb->FileLock, + FileObject, + IoGetRequestorProcess(IrpContext->Irp), + NULL + ); + } + /* Uninitialize file cache if initialized for this file object. */ if (pFcb->RFCB.Bcb != NULL) { @@ -68,7 +80,7 @@ NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext) return VfatQueueRequest (IrpContext); } - Status = VfatCleanupFile(IrpContext->DeviceExt, IrpContext->FileObject); + Status = VfatCleanupFile(IrpContext); ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource); diff --git a/reactos/drivers/fs/vfat/fcb.c b/reactos/drivers/fs/vfat/fcb.c index 5d352d5f4dd..9e81f371d14 100644 --- a/reactos/drivers/fs/vfat/fcb.c +++ b/reactos/drivers/fs/vfat/fcb.c @@ -1,4 +1,4 @@ -/* $Id: fcb.c,v 1.25 2003/01/11 15:59:07 hbirr Exp $ +/* $Id: fcb.c,v 1.26 2003/01/25 15:55:07 hbirr Exp $ * * * FILE: fcb.c @@ -62,6 +62,7 @@ vfatNewFCB(PWCHAR pFileName) rcFCB->ShortHash.self = rcFCB; ExInitializeResourceLite(&rcFCB->PagingIoResource); ExInitializeResourceLite(&rcFCB->MainResource); + FsRtlInitializeFileLock(&rcFCB->FileLock, NULL, NULL); return rcFCB; } @@ -78,6 +79,7 @@ vfatDestroyCCB(PVFATCCB pCcb) VOID vfatDestroyFCB(PVFATFCB pFCB) { + FsRtlUninitializeFileLock(&pFCB->FileLock); ExDeleteResourceLite(&pFCB->PagingIoResource); ExDeleteResourceLite(&pFCB->MainResource); if ((pFCB->Flags & FCB_IS_PAGE_FILE) && pFCB->FatChainSize) diff --git a/reactos/drivers/fs/vfat/iface.c b/reactos/drivers/fs/vfat/iface.c index 05cba8fbb4f..4a613dc6b1c 100644 --- a/reactos/drivers/fs/vfat/iface.c +++ b/reactos/drivers/fs/vfat/iface.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: iface.c,v 1.66 2002/11/11 21:49:18 hbirr Exp $ +/* $Id: iface.c,v 1.67 2003/01/25 15:55:07 hbirr Exp $ * * PROJECT: ReactOS kernel * FILE: services/fs/vfat/iface.c @@ -84,6 +84,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown; + DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest; DriverObject->DriverUnload = NULL; diff --git a/reactos/drivers/fs/vfat/misc.c b/reactos/drivers/fs/vfat/misc.c index 8a0266b55d9..f5694e4f6cc 100644 --- a/reactos/drivers/fs/vfat/misc.c +++ b/reactos/drivers/fs/vfat/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.4 2002/11/11 21:49:18 hbirr Exp $ +/* $Id: misc.c,v 1.5 2003/01/25 15:55:07 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -51,6 +51,8 @@ NTSTATUS VfatDispatchRequest ( return VfatQueryVolumeInformation(IrpContext); case IRP_MJ_SET_VOLUME_INFORMATION: return VfatSetVolumeInformation(IrpContext); + case IRP_MJ_LOCK_CONTROL: + return VfatLockControl(IrpContext); case IRP_MJ_CLEANUP: return VfatCleanup(IrpContext); default: @@ -62,6 +64,47 @@ NTSTATUS VfatDispatchRequest ( } } +NTSTATUS VfatLockControl( + IN PVFAT_IRP_CONTEXT IrpContext + ) +{ + PVFATFCB Fcb; + PVFATCCB Ccb; + NTSTATUS Status; + + DPRINT("VfatLockControl(IrpContext %x)\n", IrpContext); + + assert(IrpContext); + + Ccb = (PVFATCCB)IrpContext->FileObject->FsContext2; + Fcb = Ccb->pFcb; + + if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) + { + Status = STATUS_INVALID_DEVICE_REQUEST; + goto Fail; + } + + if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) + { + Status = STATUS_INVALID_PARAMETER; + goto Fail; + } + + Status = FsRtlProcessFileLock(&Fcb->FileLock, + IrpContext->Irp, + NULL + ); + + VfatFreeIrpContext(IrpContext); + return Status; + +Fail:; + IrpContext->Irp->IoStatus.Status = Status; + IofCompleteRequest(IrpContext->Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); + return Status; +} NTSTATUS STDCALL VfatBuildRequest ( IN PDEVICE_OBJECT DeviceObject, diff --git a/reactos/drivers/fs/vfat/rw.c b/reactos/drivers/fs/vfat/rw.c index d0b22a1daf6..736734514c7 100644 --- a/reactos/drivers/fs/vfat/rw.c +++ b/reactos/drivers/fs/vfat/rw.c @@ -1,5 +1,5 @@ -/* $Id: rw.c,v 1.53 2003/01/11 16:01:28 hbirr Exp $ +/* $Id: rw.c,v 1.54 2003/01/25 15:55:07 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -672,6 +672,17 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext) Status = STATUS_PENDING; goto ByeBye; } + + if (!(IrpContext->Irp->Flags & IRP_PAGING_IO) && + FsRtlAreThereCurrentFileLocks(&Fcb->FileLock)) + { + if (!FsRtlCheckLockForReadAccess(&Fcb->FileLock, IrpContext->Irp)) + { + Status = STATUS_FILE_LOCK_CONFLICT; + goto ByeBye; + } + } + if (!(IrpContext->Irp->Flags & (IRP_NOCACHE|IRP_PAGING_IO)) && !(Fcb->Flags & (FCB_IS_PAGE_FILE|FCB_IS_VOLUME))) { @@ -918,6 +929,16 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) } } + if (!(IrpContext->Irp->Flags & IRP_PAGING_IO) && + FsRtlAreThereCurrentFileLocks(&Fcb->FileLock)) + { + if (!FsRtlCheckLockForWriteAccess(&Fcb->FileLock, IrpContext->Irp)) + { + Status = STATUS_FILE_LOCK_CONFLICT; + goto ByeBye; + } + } + if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT) && !(Fcb->Flags & FCB_IS_VOLUME)) { if (ByteOffset.u.LowPart + Length > Fcb->RFCB.AllocationSize.u.LowPart) diff --git a/reactos/drivers/fs/vfat/vfat.h b/reactos/drivers/fs/vfat/vfat.h index 180eaacf70b..96e18687b73 100644 --- a/reactos/drivers/fs/vfat/vfat.h +++ b/reactos/drivers/fs/vfat/vfat.h @@ -1,4 +1,4 @@ -/* $Id: vfat.h,v 1.52 2003/01/24 13:42:43 ekohl Exp $ */ +/* $Id: vfat.h,v 1.53 2003/01/25 15:55:08 hbirr Exp $ */ #include @@ -199,6 +199,7 @@ typedef struct _VFATFCB SHARE_ACCESS FCBShareAccess; HASHENTRY Hash; HASHENTRY ShortHash; + FILE_LOCK FileLock; /* Structure members used only for paging files. */ ULONG FatChainSize;