-Implemented vfat file locking. (Thanks to Gunnar Andr� Dalsnes)

svn path=/trunk/; revision=4065
This commit is contained in:
Hartmut Birr 2003-01-25 15:55:08 +00:00
parent ca34b94db6
commit 4b68ac00e4
6 changed files with 89 additions and 9 deletions

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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,

View file

@ -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)

View file

@ -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 <ddk/ntifs.h>
@ -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;