xref: /reactos/drivers/filesystems/ext2/src/lock.c (revision c2c66aff)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * COPYRIGHT:        See COPYRIGHT.TXT
3*c2c66affSColin Finck  * PROJECT:          Ext2 File System Driver for WinNT/2K/XP
4*c2c66affSColin Finck  * FILE:             lock.c
5*c2c66affSColin Finck  * PROGRAMMER:       Matt Wu <mattwu@163.com>
6*c2c66affSColin Finck  * HOMEPAGE:         http://www.ext2fsd.com
7*c2c66affSColin Finck  * UPDATE HISTORY:
8*c2c66affSColin Finck  */
9*c2c66affSColin Finck 
10*c2c66affSColin Finck /* INCLUDES *****************************************************************/
11*c2c66affSColin Finck 
12*c2c66affSColin Finck #include "ext2fs.h"
13*c2c66affSColin Finck 
14*c2c66affSColin Finck /* GLOBALS ***************************************************************/
15*c2c66affSColin Finck 
16*c2c66affSColin Finck extern PEXT2_GLOBAL Ext2Global;
17*c2c66affSColin Finck 
18*c2c66affSColin Finck /* DEFINITIONS *************************************************************/
19*c2c66affSColin Finck 
20*c2c66affSColin Finck #ifdef ALLOC_PRAGMA
21*c2c66affSColin Finck #pragma alloc_text(PAGE, Ext2LockControl)
22*c2c66affSColin Finck #endif
23*c2c66affSColin Finck 
24*c2c66affSColin Finck NTSTATUS
Ext2LockControl(IN PEXT2_IRP_CONTEXT IrpContext)25*c2c66affSColin Finck Ext2LockControl (IN PEXT2_IRP_CONTEXT IrpContext)
26*c2c66affSColin Finck {
27*c2c66affSColin Finck     PDEVICE_OBJECT  DeviceObject = NULL;
28*c2c66affSColin Finck     PFILE_OBJECT    FileObject = NULL;
29*c2c66affSColin Finck     PEXT2_FCB       Fcb = NULL;
30*c2c66affSColin Finck     PIRP            Irp = NULL;
31*c2c66affSColin Finck 
32*c2c66affSColin Finck     NTSTATUS        Status = STATUS_UNSUCCESSFUL;
33*c2c66affSColin Finck     BOOLEAN         CompleteContext = TRUE;
34*c2c66affSColin Finck     BOOLEAN         CompleteIrp = TRUE;
35*c2c66affSColin Finck     BOOLEAN         bFcbAcquired = FALSE;
36*c2c66affSColin Finck 
37*c2c66affSColin Finck     _SEH2_TRY {
38*c2c66affSColin Finck 
39*c2c66affSColin Finck         ASSERT(IrpContext != NULL);
40*c2c66affSColin Finck 
41*c2c66affSColin Finck         ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
42*c2c66affSColin Finck                (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
43*c2c66affSColin Finck 
44*c2c66affSColin Finck         DeviceObject = IrpContext->DeviceObject;
45*c2c66affSColin Finck 
46*c2c66affSColin Finck         if (IsExt2FsDevice(DeviceObject)) {
47*c2c66affSColin Finck             Status = STATUS_INVALID_DEVICE_REQUEST;
48*c2c66affSColin Finck             _SEH2_LEAVE;
49*c2c66affSColin Finck         }
50*c2c66affSColin Finck 
51*c2c66affSColin Finck         FileObject = IrpContext->FileObject;
52*c2c66affSColin Finck 
53*c2c66affSColin Finck         Fcb = (PEXT2_FCB) FileObject->FsContext;
54*c2c66affSColin Finck         ASSERT(Fcb != NULL);
55*c2c66affSColin Finck         if (Fcb->Identifier.Type == EXT2VCB) {
56*c2c66affSColin Finck             Status = STATUS_INVALID_PARAMETER;
57*c2c66affSColin Finck             _SEH2_LEAVE;
58*c2c66affSColin Finck         }
59*c2c66affSColin Finck 
60*c2c66affSColin Finck         ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
61*c2c66affSColin Finck                (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
62*c2c66affSColin Finck 
63*c2c66affSColin Finck         if (FlagOn(Fcb->Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) {
64*c2c66affSColin Finck             Status = STATUS_INVALID_PARAMETER;
65*c2c66affSColin Finck             _SEH2_LEAVE;
66*c2c66affSColin Finck         }
67*c2c66affSColin Finck 
68*c2c66affSColin Finck         ExAcquireResourceSharedLite(&Fcb->MainResource, TRUE);
69*c2c66affSColin Finck         bFcbAcquired = TRUE;
70*c2c66affSColin Finck 
71*c2c66affSColin Finck         Irp = IrpContext->Irp;
72*c2c66affSColin Finck 
73*c2c66affSColin Finck         CompleteIrp = FALSE;
74*c2c66affSColin Finck 
75*c2c66affSColin Finck         Status = FsRtlCheckOplock( &Fcb->Oplock,
76*c2c66affSColin Finck                                    Irp,
77*c2c66affSColin Finck                                    IrpContext,
78*c2c66affSColin Finck                                    Ext2OplockComplete,
79*c2c66affSColin Finck                                    NULL );
80*c2c66affSColin Finck 
81*c2c66affSColin Finck         if (Status != STATUS_SUCCESS) {
82*c2c66affSColin Finck             CompleteContext = FALSE;
83*c2c66affSColin Finck             _SEH2_LEAVE;
84*c2c66affSColin Finck         }
85*c2c66affSColin Finck 
86*c2c66affSColin Finck         //
87*c2c66affSColin Finck         // FsRtlProcessFileLock acquires FileObject->FsContext->Resource while
88*c2c66affSColin Finck         // modifying the file locks and calls IoCompleteRequest when it's done.
89*c2c66affSColin Finck         //
90*c2c66affSColin Finck 
91*c2c66affSColin Finck         Status = FsRtlProcessFileLock(
92*c2c66affSColin Finck                      &Fcb->FileLockAnchor,
93*c2c66affSColin Finck                      Irp,
94*c2c66affSColin Finck                      NULL );
95*c2c66affSColin Finck #if EXT2_DEBUG
96*c2c66affSColin Finck         if (!NT_SUCCESS(Status)) {
97*c2c66affSColin Finck             DEBUG(DL_ERR, (
98*c2c66affSColin Finck                       "Ext2LockControl: %-16.16s %-31s Status: %#x ***\n",
99*c2c66affSColin Finck                       Ext2GetCurrentProcessName(),
100*c2c66affSColin Finck                       "IRP_MJ_LOCK_CONTROL",
101*c2c66affSColin Finck                       Status          ));
102*c2c66affSColin Finck         }
103*c2c66affSColin Finck #endif
104*c2c66affSColin Finck         Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
105*c2c66affSColin Finck 
106*c2c66affSColin Finck     } _SEH2_FINALLY {
107*c2c66affSColin Finck 
108*c2c66affSColin Finck         if (bFcbAcquired) {
109*c2c66affSColin Finck             ExReleaseResourceLite(&Fcb->MainResource);
110*c2c66affSColin Finck         }
111*c2c66affSColin Finck 
112*c2c66affSColin Finck         if (!IrpContext->ExceptionInProgress) {
113*c2c66affSColin Finck 
114*c2c66affSColin Finck             if (!CompleteIrp) {
115*c2c66affSColin Finck                 IrpContext->Irp = NULL;
116*c2c66affSColin Finck             }
117*c2c66affSColin Finck 
118*c2c66affSColin Finck             if (CompleteContext) {
119*c2c66affSColin Finck                 Ext2CompleteIrpContext(IrpContext, Status);
120*c2c66affSColin Finck             }
121*c2c66affSColin Finck         }
122*c2c66affSColin Finck     } _SEH2_END;
123*c2c66affSColin Finck 
124*c2c66affSColin Finck     return Status;
125*c2c66affSColin Finck }
126